[teiid-commits] teiid SVN: r1986 - in trunk: adminshell and 20 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Mar 22 17:01:49 EDT 2010


Author: shawkins
Date: 2010-03-22 17:01:44 -0400 (Mon, 22 Mar 2010)
New Revision: 1986

Added:
   trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
   trunk/client/src/main/java/org/teiid/adminapi/impl/
   trunk/client/src/main/java/org/teiid/client/plan/
   trunk/client/src/main/java/org/teiid/jdbc/
   trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java
   trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java
   trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java
   trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java
   trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java
   trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
   trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java
   trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java
   trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java
   trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java
   trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java
   trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
   trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java
   trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java
   trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java
   trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java
   trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
   trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
   trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java
   trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
   trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java
   trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java
   trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java
   trunk/client/src/main/resources/META-INF/
   trunk/client/src/main/resources/org/teiid/jdbc/
   trunk/client/src/test/java/org/teiid/jdbc/
   trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java
   trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java
   trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java
   trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java
   trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java
   trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java
   trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java
   trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
   trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java
   trunk/client/src/test/java/org/teiid/jdbc/plan/
   trunk/client/src/test/java/org/teiid/jdbc/util/
Removed:
   trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
   trunk/client-jdbc/
   trunk/engine/src/main/java/org/teiid/adminapi/impl/
Modified:
   trunk/adminshell/pom.xml
   trunk/build/assembly/client-jar.xml
   trunk/client/pom.xml
   trunk/client/src/main/java/org/teiid/client/plan/Annotation.java
   trunk/client/src/main/java/org/teiid/client/plan/DefaultDisplayHelper.java
   trunk/client/src/main/java/org/teiid/client/plan/DisplayHelper.java
   trunk/client/src/main/java/org/teiid/client/plan/PlanNode.java
   trunk/client/src/main/java/org/teiid/client/plan/PlanVisitor.java
   trunk/client/src/main/java/org/teiid/client/plan/TextOutputVisitor.java
   trunk/client/src/main/java/org/teiid/client/plan/XMLOutputVisitor.java
   trunk/client/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java
   trunk/client/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java
   trunk/console/pom.xml
   trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java
   trunk/jboss-integration/pom.xml
   trunk/pom.xml
   trunk/runtime/pom.xml
   trunk/test-integration/db/pom.xml
   trunk/test-integration/pom.xml
Log:
TEIID-918 combining client-jdbc and client

Modified: trunk/adminshell/pom.xml
===================================================================
--- trunk/adminshell/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/adminshell/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,11 +20,6 @@
       <artifactId>teiid-client</artifactId>
       <scope>provided</scope>
     </dependency>
-    <dependency>
-      <groupId>org.jboss.teiid</groupId>
-      <artifactId>teiid-client-jdbc</artifactId>
-      <scope>provided</scope>
-    </dependency>
    
     <dependency>
       <groupId>beanshell</groupId>

Modified: trunk/build/assembly/client-jar.xml
===================================================================
--- trunk/build/assembly/client-jar.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/build/assembly/client-jar.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -16,7 +16,6 @@
                
         <includes>
             <include>org.jboss.teiid:teiid-client</include>
-            <include>org.jboss.teiid:teiid-client-jdbc</include>	
             <include>org.jboss.teiid:teiid-common-core</include>	
         </includes>
         

Deleted: trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
===================================================================
(Binary files differ)

Added: trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
===================================================================
(Binary files differ)


Property changes on: trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/client/pom.xml
===================================================================
--- trunk/client/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/client/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -1,26 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <parent>
-    <artifactId>teiid</artifactId>
-    <groupId>org.jboss.teiid</groupId>
-    <version>7.0.0-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <artifactId>teiid-client</artifactId>
-  <name>Client</name>
-  <description>Contains the packages related to communication, administrative api,
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>teiid</artifactId>
+		<groupId>org.jboss.teiid</groupId>
+		<version>7.0.0-SNAPSHOT</version>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>teiid-client</artifactId>
+	<name>Client</name>
+	<description>Contains the packages related to communication, administrative api,
     sessioning and transport level messaging.</description>
-  <dependencies>
-    <dependency>
-      <groupId>org.jboss.teiid</groupId>
-      <artifactId>teiid-common-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.teiid</groupId>
-      <artifactId>teiid-common-core</artifactId>
-      <type>test-jar</type>
-    </dependency> 
-  </dependencies>
+	<dependencies>
+		<dependency>
+			<groupId>org.jboss.teiid</groupId>
+			<artifactId>teiid-common-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.teiid</groupId>
+			<artifactId>teiid-common-core</artifactId>
+			<type>test-jar</type>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.man</groupId>
+			<artifactId>jboss-managed</artifactId>
+		</dependency>
+	</dependencies>
 </project>
\ No newline at end of file

Copied: trunk/client/src/main/java/org/teiid/adminapi/impl (from rev 1983, trunk/engine/src/main/java/org/teiid/adminapi/impl)

Copied: trunk/client/src/main/java/org/teiid/client/plan (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan)

Modified: trunk/client/src/main/java/org/teiid/client/plan/Annotation.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/Annotation.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/Annotation.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 
 /**

Modified: trunk/client/src/main/java/org/teiid/client/plan/DefaultDisplayHelper.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/DefaultDisplayHelper.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/DefaultDisplayHelper.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 import java.util.ArrayList;
 import java.util.List;

Modified: trunk/client/src/main/java/org/teiid/client/plan/DisplayHelper.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/DisplayHelper.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/DisplayHelper.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 import java.util.List;
 

Modified: trunk/client/src/main/java/org/teiid/client/plan/PlanNode.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/PlanNode.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/PlanNode.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 import java.util.*;
 

Modified: trunk/client/src/main/java/org/teiid/client/plan/PlanVisitor.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/PlanVisitor.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/PlanVisitor.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 import java.util.Collection;
 import java.util.LinkedList;

Modified: trunk/client/src/main/java/org/teiid/client/plan/TextOutputVisitor.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/TextOutputVisitor.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/TextOutputVisitor.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 import java.util.Collection;
 import java.util.HashMap;

Modified: trunk/client/src/main/java/org/teiid/client/plan/XMLOutputVisitor.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/XMLOutputVisitor.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/XMLOutputVisitor.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
  * 02110-1301 USA.
  */
 
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
 
 import java.util.Collection;
 import java.util.HashMap;

Copied: trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/BaseDataSource.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,850 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+
+import org.teiid.client.RequestMessage;
+import org.teiid.net.TeiidURL;
+
+
+
+
+/**
+ * The Teiid JDBC DataSource implementation class of {@link javax.sql.DataSource} and
+ * {@link javax.sql.XADataSource}.
+ * <p>
+ * The {@link javax.sql.DataSource} interface follows the JavaBean design pattern,
+ * meaning the implementation class has <i>properties</i> that are accessed with getter methods
+ * and set using setter methods, and where the getter and setter methods follow the JavaBean
+ * naming convention (e.g., <code>get</code><i>PropertyName</i><code>() : </code><i>PropertyType</i>
+ * and <code>set</code><i>PropertyName</i><code>(</code><i>PropertyType</i><code>) : void</code>).
+ * </p>
+ * The {@link javax.sql.XADataSource} interface is almost identical to the {@link javax.sql.DataSource}
+ * interface, but rather than returning {@link java.sql.Connection} instances, there are methods that
+ * return {@link javax.sql.XAConnection} instances that can be used with distributed transactions.
+ * <p>
+ * The following are the properties for this DataSource:
+ * <table cellspacing="0" cellpadding="0" border="1" width="100%">
+ *   <tr><td><b>Property Name</b></td><td><b>Type</b></td><td><b>Description</b></td></tr>
+ *   <tr><td>applicationName  </td><td><code>String</code></td><td>The <i>optional</i> name of the application using the DataSource.</td></tr>
+ *   <tr><td>clientToken      </td><td><code>Serializable</code></td><td>The <i>optional</i> client token that will be passed directly
+ *                                                                 through to the connectors, which may use it and/or pass it
+ *                                                                 down to their underlying data source.
+ *                                                                 <p>
+ *                                                                 The form and type of the client token is up to the client but it <i>must</i> implement the
+ *                                                                 <code>Serializable</code> interface.  Teiid does nothing with this token except to make it
+ *                                                                 available for authentication/augmentation/replacement upon authentication to the system and to
+ *                                                                 connectors that may require it at the data source level.
+ *                                                                 </p></td></tr>
+ *   <tr><td>databaseName     </td><td><code>String</code></td><td>The name of a particular virtual database on a
+ *                                                                 Teiid Server.</td></tr>
+ *   <tr><td>databaseVersion  </td><td><code>String</code></td><td>The <i>optional</i> version of a particular
+ *                                                                 virtual database on a Teiid Server;
+ *                                                                 if not supplied, then the latest version is assumed.</td></tr>
+ *   <tr><td>dataSourceName   </td><td><code>String</code></td><td>The <i>optional</i> logical name for the underlying
+ *                                                                 <code>XADataSource</code> or <code>ConnectionPoolDataSource</code>;
+ *                                                                 used only when pooling connections or distributed transactions
+ *                                                                 are implemented.</td></tr>
+ *   <tr><td>description      </td><td><code>String</code></td><td>The <i>optional</i> description of this data source.</td></tr>
+ *   <tr><td>logFile          </td><td><code>String</code></td><td>The <i>optional</i> path and file name to which JDBC Log Statements
+ *                                                                 will be written; if none is specified, then no
+ *                                                                 Log Statements will be written.</td></tr>
+ *   <tr><td>logLevel         </td><td><code>int   </code></td><td>The <i>optional</i> level for logging, which only applies
+ *                                                                 if the <code>logFile</code> property is set.  Value must be
+ *                                                                 one of the following:
+ *                                                                 <ul>
+ *                                                                    <li>"<code>0</code>" - no JDBC log messages will be written to the file;
+ *                                                                         this is the default</li>
+ *                                                                    <li>"<code>1</code>" - all JDBC log messages will be written to the file</li>
+ *                                                                    <li>"<code>2</code>" - all JDBC log messages as well as stack traces
+ *                                                                         of any exceptions thrown from this driver will be written
+ *                                                                         to the file</li>
+ *                                                                 </ul>
+ *   <tr><td>password</td><td><code>String</code></td><td>The user's password.</td></tr>
+ *   <tr><td>user</td><td><code>String</code></td><td>The user name to use for the connection.</td></tr>
+ *   <tr><td>partialResultsMode</td><td><code>boolean</code></td><td>Support partial results mode or not. </td></tr>
+ *   <tr><td>fetchSize</td><td><code>int</code></td><td>Set default fetch size for statements, default=500.</td></tr>
+ *   <tr><td>sqlOptions</td><td><code>String</code></td><td>Set sql options to use on every command. default=null</td></tr>
+ * <table>
+ * </p>
+ */
+public abstract class BaseDataSource extends WrapperImpl implements javax.sql.DataSource, XADataSource, ConnectionPoolDataSource, java.io.Serializable {
+	public static final String DEFAULT_APP_NAME = "JDBC"; //$NON-NLS-1$
+	
+    // constant indicating Virtual database name
+    public static final String VDB_NAME = TeiidURL.JDBC.VDB_NAME; 
+    // constant indicating Virtual database version
+    public static final String VDB_VERSION = TeiidURL.JDBC.VDB_VERSION; 
+    // constant for vdb version part of serverURL
+    public static final String VERSION = TeiidURL.JDBC.VERSION; 
+    // name of the application which is obtaining connection
+    public static final String APP_NAME = TeiidURL.CONNECTION.APP_NAME; 
+    // constant for username part of url
+    public static final String USER_NAME = TeiidURL.CONNECTION.USER_NAME; 
+    // constant for password part of url
+    public static final String PASSWORD = TeiidURL.CONNECTION.PASSWORD; 
+    
+    protected static final int DEFAULT_TIMEOUT = 0;
+    protected static final int DEFAULT_LOG_LEVEL = 0;
+
+    /**
+     * The name of the virtual database on a particular Teiid Server.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>required</i>.
+     */
+    private String databaseName;
+
+    /**
+     * The logical name for the underlying <code>XADataSource</code> or
+     * <code>ConnectionPoolDataSource</code>;
+     * used only when pooling connections or distributed transactions are implemented.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>optional</i>.
+     */
+    private String dataSourceName;
+
+    /**
+     * The description of this data source.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>optional</i>.
+     */
+    private String description;
+
+
+    /**
+     * The user's name.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>required</i>.
+     */
+    private String user;
+
+    /**
+     * The user's password.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>required</i>.
+     */
+    private String password;
+
+    /**
+     * The version number of the virtual database to which a connection is to be established.
+     * This property is <i>optional</i>; if not specified, the assumption is that the latest version
+     * on the Teiid Server is to be used.
+     */
+    private String databaseVersion;
+
+    /**
+     * The name of the application.  Supplying this property may allow an administrator of a
+     * Teiid Server to better identify individual connections and usage patterns.
+     * This property is <i>optional</i>.
+     */
+    private String applicationName;
+
+    /** Support partial results mode or not.*/
+    private String partialResultsMode;
+    
+    /** Default fetch size, <= 0 indicates not set. */
+    private int fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+
+    /** Whether to use result set cache if it available **/
+    private String resultSetCacheMode;
+    
+    /**
+     * The number of milliseconds before timing out.
+     * This property is <i>optional</i> and defaults to "0" (meaning no time out).
+     */
+    private int loginTimeout;
+    
+    private String sqlOptions;
+    
+    private String disableLocalTxn;
+
+    private String transactionAutoWrap;
+    
+    private boolean ansiQuotedIdentifiers = true;
+    
+    /**
+     * Reference to the logWriter, which is transient and is therefore not serialized with the DataSource.
+     */
+    private transient PrintWriter logWriter;
+    public static final String JDBC = "jdbc:"; //$NON-NLS-1$
+    // Default execution property constants
+    protected static final int DEFAULT_FETCH_SIZE = RequestMessage.DEFAULT_FETCH_SIZE;
+    protected static final String DEFAULT_PARTIAL_RESULTS_MODE = "FALSE"; //$NON-NLS-1$
+    protected static final String DEFAULT_RESULT_SET_CACHE_MODE = "TRUE"; //$NON-NLS-1$
+    
+    /**
+     * Transaction auto wrap constant - never wrap a command execution in a transaction
+     * and allow multi-source updates to occur outside of a transaction.
+     */
+    public static final String TXN_WRAP_OFF = ExecutionProperties.TXN_WRAP_OFF;
+
+    /**
+     * Transaction auto wrap constant - always wrap every non-transactional command
+     * execution in a transaction.
+     */
+    public static final String TXN_WRAP_ON = ExecutionProperties.TXN_WRAP_ON;
+
+    /**
+     * Transaction auto wrap constant - checks if a command
+     * requires a transaction and will be automatically wrap it.
+     */
+    public static final String TXN_WRAP_AUTO = ExecutionProperties.TXN_WRAP_DETECT;
+
+    /**
+     * String to hold additional properties that are not represented with an explicit getter/setter
+     */
+    private String additionalProperties;
+    
+    /**
+     * Constructor for MMDataSource.
+     */
+    public BaseDataSource() {
+        this.loginTimeout = DEFAULT_TIMEOUT;
+    }
+
+    // --------------------------------------------------------------------------------------------
+    //                             H E L P E R   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    protected Properties buildProperties(final String userName, final String password) {
+        Properties props = new Properties();
+        props.setProperty(BaseDataSource.VDB_NAME,this.getDatabaseName());
+
+        if ( this.getDatabaseVersion() != null && this.getDatabaseVersion().trim().length() != 0  ) {
+            props.setProperty(BaseDataSource.VDB_VERSION,this.getDatabaseVersion());
+        }
+
+        if ( userName != null && userName.trim().length() != 0) {
+            props.setProperty(BaseDataSource.USER_NAME, userName);
+        } else if ( this.getUser() != null && this.getUser().trim().length() != 0) {
+            props.setProperty(BaseDataSource.USER_NAME, this.getUser());
+        }
+
+        if ( password != null && password.trim().length() != 0) {
+            props.setProperty(BaseDataSource.PASSWORD, password);
+        } else if ( this.getPassword() != null && this.getPassword().trim().length() != 0) {
+            props.setProperty(BaseDataSource.PASSWORD, this.getPassword());
+        }
+
+        if ( this.getApplicationName() != null && this.getApplicationName().trim().length() != 0 ) {
+            props.setProperty(BaseDataSource.APP_NAME,this.getApplicationName());
+        }
+        
+        if (this.getPartialResultsMode() != null && this.getPartialResultsMode().trim().length() != 0) {
+            props.setProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, this.getPartialResultsMode());
+        }
+        
+        if(this.getFetchSize() > 0) {
+            props.setProperty(ExecutionProperties.PROP_FETCH_SIZE, "" + this.getFetchSize()); //$NON-NLS-1$
+        }
+
+        if (this.getResultSetCacheMode() != null && this.getResultSetCacheMode().trim().length() != 0) {
+            props.setProperty(ExecutionProperties.RESULT_SET_CACHE_MODE, this.getResultSetCacheMode());
+        }
+        
+        if (this.getSqlOptions() != null) {
+            props.setProperty(ExecutionProperties.PROP_SQL_OPTIONS, this.getSqlOptions());
+        }
+        
+        if ( this.getTransactionAutoWrap() != null && this.getTransactionAutoWrap().trim().length() != 0   ) {
+            props.setProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP, this.getTransactionAutoWrap());
+        }
+        
+        if (this.getDisableLocalTxn() != null) {
+            props.setProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS, this.getDisableLocalTxn());
+        }
+        
+        if (this.additionalProperties != null) {
+        	JDBCURL.parseConnectionProperties(this.additionalProperties, props);
+        }
+                      
+        return props;
+    }
+
+    protected void validateProperties( final String userName, final String password) throws java.sql.SQLException {
+        String reason = reasonWhyInvalidApplicationName(this.applicationName);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidDatabaseName(this.databaseName);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidDatabaseVersion(this.databaseVersion);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidDataSourceName(this.dataSourceName);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidDescription(this.description);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        final String pwd = password != null ? password : getPassword();
+        reason = reasonWhyInvalidPassword(pwd);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidPartialResultsMode(this.partialResultsMode);
+        if (reason != null) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidFetchSize(this.fetchSize);
+        if (reason != null) {
+            throw new SQLException(reason);
+        }
+
+        final String user = userName != null ? userName : getUser();
+        reason = reasonWhyInvalidUser(user);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+
+        reason = reasonWhyInvalidTransactionAutoWrap(this.transactionAutoWrap);
+        if ( reason != null ) {
+            throw new SQLException(reason);
+        }
+                
+        
+    }
+
+    // --------------------------------------------------------------------------------------------
+    //                        D A T A S O U R C E   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    /**
+     * Attempt to establish a database connection.
+     * @return a Connection to the database
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#getConnection()
+     */
+    public Connection getConnection() throws java.sql.SQLException {
+        return getConnection(null,null);
+    }
+    
+    /** 
+     * @see javax.sql.XADataSource#getXAConnection()
+     */
+    public XAConnection getXAConnection() throws SQLException {
+        return getXAConnection(null,null);
+    }
+    
+    /**
+     * Attempt to establish a database connection that can be used with distributed transactions.
+     * @param userName the database user on whose behalf the XAConnection is being made
+     * @param password the user's password
+     * @return an XAConnection to the database
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.XADataSource#getXAConnection(java.lang.String, java.lang.String)
+     */
+    public XAConnection getXAConnection(final String userName, final String password) throws java.sql.SQLException {
+    	return XAConnectionImpl.newInstance(new XAConnectionImpl.ConnectionSource() {
+
+            public ConnectionImpl createConnection() throws SQLException {
+                return (ConnectionImpl)getConnection(userName, password);
+            }});
+    }
+    
+    public PooledConnection getPooledConnection() throws SQLException {
+		return getPooledConnection(null, null);
+	}
+
+	public PooledConnection getPooledConnection(final String userName, final String password)
+			throws SQLException {
+		return getXAConnection(userName, password);
+	}
+	
+    // --------------------------------------------------------------------------------------------
+    //                        P R O P E R T Y   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+	public String getDisableLocalTxn() {
+		return disableLocalTxn;
+	}
+
+	public void setDisableLocalTxn(String disableLocalTxn) {
+		this.disableLocalTxn = disableLocalTxn;
+	}
+
+    /**
+     * Get the log writer for this data source.
+     * <p>
+     * The log writer is a character output stream to which all logging and tracing
+     * messages for this data source object instance will be printed. This includes
+     * messages printed by the methods of this object, messages printed by methods
+     * of other objects manufactured by this object, and so on. Messages printed
+     * to a data source specific log writer are not printed to the log writer
+     * associated with the {@link java.sql.DriverManager} class. When a DataSource object is
+     * created the log writer is initially null, in other words, logging is disabled.
+     * @return the log writer for this data source, null if disabled
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#getLogWriter()
+     */
+    public PrintWriter getLogWriter() throws java.sql.SQLException{
+        return this.logWriter;
+    }
+
+    /**
+     * Gets the maximum time in seconds that this data source can wait while attempting
+     * to connect to a database. A value of zero means that the timeout is the default
+     * system timeout if there is one; otherwise it means that there is no timeout.
+     * When a DataSource object is created the login timeout is initially zero.
+     * @return the data source login time limit
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#getLoginTimeout()
+     */
+    public int getLoginTimeout() throws java.sql.SQLException {
+        return this.loginTimeout;
+    }
+
+    /**
+     * Set the log writer for this data source.
+     * <p>
+     * The log writer is a character output stream to which all logging and tracing
+     * messages for this data source object instance will be printed. This includes
+     * messages printed by the methods of this object, messages printed by methods
+     * of other objects manufactured by this object, and so on. Messages printed
+     * to a data source specific log writer are not printed to the log writer
+     * associated with the {@link java.sql.DriverManager} class. When a DataSource object is
+     * created the log writer is initially null, in other words, logging is disabled.
+     * @param writer the log writer for this data source, null if disabled
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter)
+     */
+    public void setLogWriter( final PrintWriter writer) throws java.sql.SQLException{
+        this.logWriter = writer;
+    }
+
+    /**
+     * Sets the maximum time in seconds that this data source can wait while attempting
+     * to connect to a database. A value of zero means that the timeout is the default
+     * system timeout if there is one; otherwise it means that there is no timeout.
+     * When a DataSource object is created the login timeout is initially zero.
+     * @param timeOut the data source login time limit
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#setLoginTimeout(int)
+     */
+    public void setLoginTimeout( final int timeOut) throws java.sql.SQLException {
+        this.loginTimeout = timeOut;
+    }
+
+    /**
+     * Returns the name of the application.  Supplying this property may allow an administrator of a
+     * Teiid Server to better identify individual connections and usage patterns.
+     * This property is <i>optional</i>.
+     * @return String the application name; may be null or zero-length
+     */
+    public String getApplicationName() {
+        return applicationName!=null?applicationName:DEFAULT_APP_NAME;
+    }
+
+    /**
+     * Returns the name of the virtual database on a particular Teiid Server.
+     * @return String
+     */
+    public String getDatabaseName() {
+        return databaseName;
+    }
+
+    /**
+     * Returns the databaseVersion.
+     * @return String
+     */
+    public String getDatabaseVersion() {
+        return databaseVersion;
+    }
+
+    /**
+     * Returns the logical name for the underlying <code>XADataSource</code> or
+     * <code>ConnectionPoolDataSource</code>;
+     * used only when pooling connections or distributed transactions are implemented.
+     * @return the logical name for the underlying data source; may be null
+     */
+    public String getDataSourceName() {
+        return dataSourceName;
+    }
+
+    /**
+     * Returns the description of this data source.
+     * @return the description; may be null
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Returns the user.
+     * @return the name of the user for this data source
+     */
+    public String getUser() {
+        return user;
+    }
+
+    /**
+     * Returns the password.
+     * @return the password for this data source.
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+<     * Sets the name of the application.  Supplying this property may allow an administrator of a
+     * Teiid Server to better identify individual connections and usage patterns.
+     * This property is <i>optional</i>.
+     * @param applicationName The applicationName to set
+     */
+    public void setApplicationName(final String applicationName) {
+        this.applicationName = applicationName;
+    }
+
+    /**
+     * Sets the name of the virtual database on a particular Teiid Server.
+     * @param databaseName The name of the virtual database
+     */
+    public void setDatabaseName(final String databaseName) {
+        this.databaseName = databaseName;
+    }
+
+    /**
+     * Sets the databaseVersion.
+     * @param databaseVersion The version of the virtual database
+     */
+    public void setDatabaseVersion(final String databaseVersion) {
+        this.databaseVersion = databaseVersion;
+    }
+
+    /**
+     * Sets the logical name for the underlying <code>XADataSource</code> or
+     * <code>ConnectionPoolDataSource</code>;
+     * used only when pooling connections or distributed transactions are implemented.
+     * @param dataSourceName The dataSourceName for this data source; may be null
+     */
+    public void setDataSourceName(final String dataSourceName) {
+        this.dataSourceName = dataSourceName;
+    }
+
+    /**
+     * Sets the user.
+     * @param user The user to set
+     */
+    public void setUser(final String user) {
+        this.user = user;
+    }
+
+    /**
+     * Sets the password.
+     * @param password The password for this data source
+     */
+    public void setPassword(final String password) {
+        this.password = password;
+    }
+
+    /**
+     * Sets the description of this data source.
+     * @param description The description for this data source; may be null
+     */
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+
+    public void setPartialResultsMode(String partialResultsMode) {
+        this.partialResultsMode = partialResultsMode;
+    }
+
+    public String getPartialResultsMode() {
+        return this.partialResultsMode;
+    }
+
+    public void setFetchSize(int fetchSize) {
+        this.fetchSize = fetchSize;
+    }
+
+    public int getFetchSize() {
+        return this.fetchSize;
+    }
+    
+    public void setResultSetCacheMode(String resultSetCacheMode) {
+        this.resultSetCacheMode = resultSetCacheMode;
+    }
+
+    public String getResultSetCacheMode() {
+        return this.resultSetCacheMode;
+    }
+    
+    /**
+     * Get special sqlOptions string, which can currently be set only to SHOWPLAN
+     * @return Returns sqlOptions string or null if none
+     * @since 4.3
+     */
+    public String getSqlOptions() {
+        return this.sqlOptions;
+    }
+    
+    /** 
+     * Sets special sqlOptions that should be used with each command.
+     * @param sqlOptions SQL options, only "SHOWPLAN" is currently accepted
+     * @since 4.3
+     */
+    public void setSqlOptions(String sqlOptions) {
+        this.sqlOptions = sqlOptions;
+    }
+
+    /**
+     * @deprecated
+     * @see #getAutoCommitTxn()
+     * @return
+     */
+    public String getTransactionAutoWrap() {
+        return transactionAutoWrap;
+    }
+
+    /**
+     * @deprecated
+     * @see #setAutoCommitTxn(String)
+     * @param transactionAutoWrap
+     */
+    public void setTransactionAutoWrap(String transactionAutoWrap) {
+        this.transactionAutoWrap = transactionAutoWrap;
+    }
+
+    /**
+     * Returns the current setting for how connections are created by this DataSource manage transactions
+     * for client requests when client applications do not use transactions.
+     * Because a virtual database will likely deal with multiple underlying information sources,
+     * Teiid will execute all client requests within the contexts of transactions.
+     * This method determines the semantics of creating such transactions when the client does not
+     * explicitly do so.
+     * @return the current setting, or null if the property has not been set and the default mode will
+     * be used.
+     */
+    public String getAutoCommitTxn() {
+		return this.transactionAutoWrap;
+	}
+    
+    /**
+     * Sets the setting for how connections are created by this DataSource manage transactions
+     * for client requests with autoCommit = true.
+     * Because a virtual database will likely deal with multiple underlying information sources,
+     * Teiid will execute all client requests within the contexts of transactions.
+     * This method determines the semantics of creating such transactions when the client does not
+     * explicitly do so.
+     * <p>
+     * The allowable values for this property are:
+     * <ul>
+     *   <li>"<code>OFF</code>" - Nothing is ever wrapped in a transaction and the server will execute
+     * multi-source updates happily but outside a transaction.  This is least safe but highest performance.
+     * The {@link #TXN_WRAP_OFF} constant value is provided for convenience.</li>
+     *   <li>"<code>ON</code>" - Always wrap every command in a transaction.  This is most safe but lowest
+     * performance.
+     * The {@link #TXN_WRAP_ON} constant value is provided for convenience.</li>
+     *   <li>"<code>AUTO</code>" - checks if a command requires a transaction and will be automatically wrap it.
+     * This is the default mode.
+     * The {@link #TXN_WRAP_AUTO} constant value is provided for convenience.</li>
+     * </ul>
+     * </p>
+     * @param transactionAutoWrap The transactionAutoWrap to set
+     */
+    public void setAutoCommitTxn(String transactionAutoWrap) {
+    	this.transactionAutoWrap = transactionAutoWrap;
+    }
+
+    // --------------------------------------------------------------------------------------------
+    //                  V A L I D A T I O N   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    /**
+     * Return the reason why the supplied application name may be invalid, or null
+     * if it is considered valid.
+     * @param applicationName a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setApplicationName(String)
+     */
+    public static String reasonWhyInvalidApplicationName( final String applicationName ) {
+        return null;        // anything is valid
+    }
+
+
+
+    /**
+     * Return the reason why the supplied virtual database name may be invalid, or null
+     * if it is considered valid.
+     * @param databaseName a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setDatabaseName(String)
+     */
+    public static String reasonWhyInvalidDatabaseName( final String databaseName ) {
+        if ( databaseName == null || databaseName.trim().length() == 0 ) {                                  
+            return JDBCPlugin.Util.getString("MMDataSource.Virtual_database_name_must_be_specified"); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Return the reason why the supplied user name may be invalid, or null
+     * if it is considered valid.
+     * @param userName a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setUser(String)
+     */
+    public static String reasonWhyInvalidUser( final String userName ) {
+        return null;
+    }
+
+    /**
+     * Return the reason why the supplied transaction auto wrap value may be invalid, or null
+     * if it is considered valid.
+     * <p>
+     * This method checks to see that the value is one of the allowable values.
+     * </p>
+     * @param autoWrap a possible value for the auto wrap property.
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setTransactionAutoWrap(String)
+     */
+    public static String reasonWhyInvalidTransactionAutoWrap( final String autoWrap ) {
+        if ( autoWrap == null || autoWrap.trim().length() == 0 ) {
+            return null;    // no longer require an app server name, 'cause will look on classpath
+        }
+        final String trimmedAutoWrap = autoWrap.trim();
+        if( TXN_WRAP_ON.equals(trimmedAutoWrap) ) {
+            return null;
+        }
+        if( TXN_WRAP_OFF.equals(trimmedAutoWrap) ) {
+            return null;
+        }
+        if( TXN_WRAP_AUTO.equals(trimmedAutoWrap) ) {
+            return null;
+        }
+
+        Object[] params = new Object[] {
+            TXN_WRAP_ON, TXN_WRAP_OFF, TXN_WRAP_AUTO };
+        return JDBCPlugin.Util.getString("MMDataSource.Invalid_trans_auto_wrap_mode", params); //$NON-NLS-1$
+    }
+         
+    /**
+     * Return the reason why the supplied virtual database version may be invalid, or null
+     * if it is considered valid.
+     * @param databaseVersion a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setDatabaseVersion(String)
+     */
+    public static String reasonWhyInvalidDatabaseVersion( final String databaseVersion ) {
+        return null;        // anything is valid (let server validate)
+    }
+
+    /**
+     * Return the reason why the supplied data source name may be invalid, or null
+     * if it is considered valid.
+     * @param dataSourceName a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setDataSourceName(String)
+     */
+    public static String reasonWhyInvalidDataSourceName( final String dataSourceName) {
+        return null;        // anything is valid
+    }
+
+    /**
+     * Return the reason why the supplied password may be invalid, or null
+     * if it is considered valid.
+     * @param pwd a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setPassword(String)
+     */
+    public static String reasonWhyInvalidPassword( final String pwd ) {
+        return null;
+    }
+
+    /**
+     * Return the reason why the supplied description may be invalid, or null
+     * if it is considered valid.
+     * @param description a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setDescription(String)
+     */
+    public static String reasonWhyInvalidDescription( final String description ) {
+        return null;        // anything is valid
+    }
+
+    /**
+     * The reason why partialResultsMode is invalid.
+     * @param partialMode boolean flag
+     * @return String reason
+     */
+    public static String reasonWhyInvalidPartialResultsMode( final String partialMode) {
+        if ( partialMode != null ) {
+            if (partialMode.equalsIgnoreCase("true") || partialMode.equalsIgnoreCase("false")) { //$NON-NLS-1$ //$NON-NLS-2$
+                return null;
+            }
+            return JDBCPlugin.Util.getString("MMDataSource.The_partial_mode_must_be_boolean._47"); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * The reason why fetchSize is invalid.
+     * @param fetchSize Number of rows per batch
+     * @return the reason why the property is invalid, or null if it is considered valid
+     */
+    public static String reasonWhyInvalidFetchSize( final int fetchSize) {
+        if ( fetchSize <= 0 ) {
+            return JDBCPlugin.Util.getString("MMDataSource.The_fetch_size_must_be_greater_than_zero"); //$NON-NLS-1$
+        }
+        return null;
+    }
+    
+	public void setAdditionalProperties(String additionalProperties) {
+		this.additionalProperties = additionalProperties;
+	}
+
+	public String getAdditionalProperties() {
+		return additionalProperties;
+	}
+
+	public void setAnsiQuotedIdentifiers(boolean ansiQuotedIdentifiers) {
+		this.ansiQuotedIdentifiers = ansiQuotedIdentifiers;
+	}
+
+	public boolean isAnsiQuotedIdentifiers() {
+		return ansiQuotedIdentifiers;
+	}
+
+}
+

Copied: trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/BatchResults.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,255 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.metamatrix.core.util.Assertion;
+
+/** 
+ * @since 4.3
+ */
+public class BatchResults {
+	
+	public interface BatchFetcher {
+		Batch requestBatch(int beginRow) throws SQLException;
+	}
+		
+	static class Batch{
+	    private List[] batch;
+	    private int beginRow;
+	    private int endRow;
+	    private boolean isLast;
+	    
+	    Batch(List[] batch, int beginRow, int endRow, boolean isLast){
+	        this.batch = batch;
+	        this.beginRow = beginRow;
+	        this.endRow = endRow;
+	        this.isLast = isLast;
+	    }
+	    
+	    int getLength() {
+	        return batch.length;
+	    }
+	    
+	    List getRow(int index) {
+	        return batch[index - beginRow];
+	    }
+	    
+	    int getBeginRow() {
+	        return beginRow;
+	    }
+	    
+	    int getEndRow() {
+	        return endRow;
+	    }
+	    
+	    boolean isLast() {
+	        return isLast;
+	    }
+	    
+	}
+	
+	static final int DEFAULT_SAVED_BATCHES = 3;
+		
+    private ArrayList<Batch> batches = new ArrayList<Batch>();
+    
+    private int currentRowNumber;
+    private List<?> currentRow;
+    private int lastRowNumber = -1;
+    private int highestRowNumber;
+    private BatchFetcher batchFetcher;
+    private int savedBatches = DEFAULT_SAVED_BATCHES;
+    
+    public BatchResults(List[] batch, int beginRow, int endRow, boolean isLast) {
+    	this.setBatch(new Batch(batch, beginRow, endRow, isLast));
+    }
+    
+    public BatchResults(BatchFetcher batchFetcher, Batch batch, int savedBatches) {
+		this.batchFetcher = batchFetcher;
+		this.savedBatches = savedBatches;
+		this.setBatch(batch);
+	}
+
+    /**
+     * Moving forward through the results it's expected that the batches are arbitrarily size.
+     * Moving backward through the results it's expected that the batches will match the fetch size.
+     */
+	public List getCurrentRow() throws SQLException {
+		if (currentRow != null) {
+			return currentRow;
+		}
+    	if (this.currentRowNumber == 0 || (lastRowNumber != -1 && this.currentRowNumber > lastRowNumber)) {
+    		return null;
+    	}
+    	for (int i = 0; i < batches.size(); i++) {
+    		Batch batch = batches.get(i);
+    		if (this.currentRowNumber < batch.getBeginRow()) {
+    			continue;
+    		}
+			if (this.currentRowNumber > batch.getEndRow()) {
+				continue;
+			}
+			if (i != 0) {
+				batches.add(0, batches.remove(i));
+			}
+			currentRow = batch.getRow(this.currentRowNumber);
+			return currentRow;
+		}
+		requestBatchAndWait(this.currentRowNumber);
+    	Batch batch = batches.get(0);
+        currentRow = batch.getRow(this.currentRowNumber);
+        return currentRow;
+    }
+    
+	private void requestNextBatch() throws SQLException {
+		requestBatchAndWait(highestRowNumber + 1);
+	}
+    
+    public boolean next() throws SQLException{
+    	if (hasNext()) {
+    		setCurrentRowNumber(this.currentRowNumber + 1);
+    		getCurrentRow();
+            return true;
+    	}
+    	
+    	if (this.currentRowNumber == highestRowNumber) {
+    		setCurrentRowNumber(this.currentRowNumber + 1);
+    	}
+    	
+    	return false;
+    }
+    
+    public boolean hasPrevious() {
+        return (this.currentRowNumber != 0 && this.currentRowNumber != 1);
+    }
+    
+    public boolean previous() {
+        if (hasPrevious()) {
+        	setCurrentRowNumber(this.currentRowNumber - 1);
+        	return true;
+        }
+        
+        if (this.currentRowNumber == 1) {
+        	setCurrentRowNumber(this.currentRowNumber - 1);
+        }
+        
+        return false;
+    }
+                
+    public void setBatchFetcher(BatchFetcher batchFetcher) {
+        this.batchFetcher = batchFetcher;
+    }
+    
+    public boolean absolute(int row) throws SQLException {
+    	return absolute(row, 0);
+    }
+    
+    public boolean absolute(int row, int offset) throws SQLException {
+        if(row == 0) {
+            setCurrentRowNumber(0);
+            return false;
+        }
+        
+        if (row > 0) {
+        	//row is greater than highest, but the last row is not known
+        	while (row + offset > highestRowNumber && lastRowNumber == -1) {
+        		requestNextBatch();
+        	}
+
+        	if (row + offset <= highestRowNumber) {
+        		setCurrentRowNumber(row);
+        		return true;
+        	}
+
+    		setCurrentRowNumber(lastRowNumber + 1 - offset);
+    		return false;
+        }
+        
+        row -= offset;
+        
+        while (lastRowNumber == -1) {
+        	requestNextBatch();
+        }
+        
+        int positiveRow = lastRowNumber + row + 1;
+        
+        if (positiveRow <= 0) {
+        	setCurrentRowNumber(0);
+        	return false;
+        }
+        
+        setCurrentRowNumber(positiveRow);
+        return true;
+    }
+    
+    public int getCurrentRowNumber() {
+        return currentRowNumber;
+    }
+        
+    private void requestBatchAndWait(int beginRow) throws SQLException{
+    	if (batches.size() == savedBatches) {
+        	batches.remove(savedBatches - 1);
+        }
+    	setBatch(batchFetcher.requestBatch(beginRow));
+	}
+
+	private void setBatch(Batch batch) {
+		Assertion.assertTrue(batch.getLength() != 0 || batch.isLast());
+		if (batch.isLast()) {
+            this.lastRowNumber = batch.getEndRow();
+        }
+        highestRowNumber = Math.max(batch.getEndRow(), highestRowNumber); 
+        this.batches.add(0, batch);
+	}
+
+	public boolean hasNext() throws SQLException {
+		return hasNext(1);
+	}
+
+	public boolean hasNext(int next) throws SQLException {
+    	while (this.currentRowNumber + next > highestRowNumber && lastRowNumber == -1) {
+			requestNextBatch();
+        }
+        
+        return (this.currentRowNumber + next <= highestRowNumber);
+	}
+
+	public int getFinalRowNumber() {
+		return lastRowNumber;
+	}
+
+	public int getHighestRowNumber() {
+		return highestRowNumber;
+	}
+
+	private void setCurrentRowNumber(int currentRowNumber) {
+		if (currentRowNumber != this.currentRowNumber) {
+			this.currentRow = null;
+		}
+		this.currentRowNumber = currentRowNumber;
+	}
+       
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/CallableStatementImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,788 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.SQLXML;
+import java.sql.NClob;
+import java.sql.RowId;
+//## JDBC4.0-end ##
+
+/*## JDBC3.0-JDK1.5-begin ##
+import com.metamatrix.core.jdbc.SQLXML; 
+## JDBC3.0-JDK1.5-end ##*/
+
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+import org.teiid.client.RequestMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.RequestMessage.StatementType;
+
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.common.util.TimestampWithTimezone;
+
+/**
+ * <p> This class inherits Statement methods, which deal with SQL statements in
+ * general and also inherits PreparedStatement methods, which deal with IN parameters.
+ * This object provides a way to call stored procedures.  This call
+ * is written in an escape syntax that may take one of two forms: one form with
+ * result parameter, and the other without one.  A result parameter, a kind of OUT
+ * parameter is the return value for the stored procedure.  Both forms may have a
+ * variable number of parameters used for input(IN parameters), output(OUT parameters),
+ * or both (INOUT parameters).</p>
+ * <p> The methods in this class can be used to retrieve values of OUT parameters or
+ * the output aspect of INOUT parameters.</p>
+ */
+public class CallableStatementImpl extends PreparedStatementImpl implements CallableStatement {
+
+    // object representing parameter value
+    private Object parameterValue;
+
+    /**
+     * Factory Constructor (be sure to cast it to  MMCallableStatement)
+     */
+    static CallableStatementImpl newInstance(ConnectionImpl connection, String procedureCall, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return new CallableStatementImpl(connection, procedureCall, resultSetType, resultSetConcurrency);        
+    }
+    
+    /**
+     * <p>MMCallableStatement constructor that sets the procedureName, IN parameters
+     * and OUT parameters on this object.
+     * @param Driver's connection object which creates this object.
+     * @param procedureCall string
+     * @throws SQLException if there is an error parsing the call
+     */
+    CallableStatementImpl(ConnectionImpl connection, String procedureCall, int resultSetType, int resultSetConcurrency) throws SQLException {
+        // set the connection on the super class
+        super(connection, procedureCall, resultSetType, resultSetConcurrency);
+        this.prepareSql = procedureCall;
+    }
+    
+    @Override
+    protected RequestMessage createRequestMessage(String[] commands,
+    		boolean isBatchedCommand, ResultsMode resultsMode) {
+    	RequestMessage message = super.createRequestMessage(commands, isBatchedCommand, resultsMode);
+    	message.setStatementType(StatementType.CALLABLE);
+    	return message;
+    }
+    
+    /**
+     * In many cases, it is desirable to immediately release a Statements's database
+     * and JDBC resources instead of waiting for this to happen when it is automatically
+     * closed; the close method provides this immediate release.
+     * @throws SQLException should never occur.
+     */
+    public void close() throws SQLException {
+        this.prepareSql = null;
+        super.close();
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.math.BigDecimal object with
+     * scale digits to the right of the decimal point.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as an BigDecimal object.
+     * @throws SQLException if param datatype is not NUMERIC
+     * @deprecated
+     */
+    public java.math.BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
+        BigDecimal bigDecimalParam = DataTypeTransformer.getBigDecimal(getObject(parameterIndex));
+
+        // set scale on the param value
+        bigDecimalParam.setScale(scale);
+
+        // return param value
+        return bigDecimalParam;
+    }
+    
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.math.BigDecimal object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as an BigDecimal object.
+     * @throws SQLException if param datatype is not NUMERIC
+     */
+    public java.math.BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getBigDecimal(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Blob object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a Blob object.
+     */
+    public Blob getBlob(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getBlob(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a boolean.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a boolean value.
+     * @throws SQLException if param datatype is not BIT
+     */
+    public boolean getBoolean(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getBoolean(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a byte.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a byte value.
+     * @throws SQLException if param datatype is not TINYINT
+     */
+    public byte getByte(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getByte(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Clob object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a Clob object.
+     */
+    public Clob getClob(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getClob(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Date object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a Date object.
+     * @throws SQLException if param datatype is not DATE
+     */
+    public java.sql.Date getDate(int parameterIndex) throws SQLException {
+        return getDate(parameterIndex, null);
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Date object. Calender
+     * object contains the timezone info for the Date.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @param Calendar object used to construct the Date object.
+     * @return The parameter at the given index is returned as a Date object.
+     * @throws SQLException if param datatype is not DATE
+     */
+    public java.sql.Date getDate(int parameterIndex, Calendar cal) throws SQLException {
+        Date value = DataTypeTransformer.getDate(getObject(parameterIndex));
+
+        if (value == null) {
+            return null;
+        }
+        
+        if (cal != null) {
+            value = TimestampWithTimezone.createDate(value, getDefaultCalendar().getTimeZone(), cal);
+        }
+        
+        return value;
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a double.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a double value.
+     * @throws SQLException if param datatype is not DOUBLE or FLOAT
+     */
+    public double getDouble(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getDouble(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a float.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a float value.
+     * @throws SQLException if param datatype is not FLOAT
+     */
+    public float getFloat(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getFloat(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a int.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a int value.
+     * @throws SQLException if param datatype is not INTEGER
+     */
+    public int getInt(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getInteger(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a long.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a long value.
+     * @throws SQLException if param datatype is not BIGINT
+     */
+    public long getLong(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getLong(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as an object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as an object.
+     * @throws SQLException
+     */
+    public Object getObject(int parameterIndex) throws SQLException {
+        //checkParameter(parameterIndex);
+
+        Object indexInResults = this.outParamIndexMap.get(new Integer(parameterIndex));
+        if(indexInResults == null){
+            throw new IllegalArgumentException(JDBCPlugin.Util.getString("MMCallableStatement.Param_not_found", parameterIndex)); //$NON-NLS-1$
+        }
+        checkStatement();
+        parameterValue = resultSet.getOutputParamValue(((Integer)indexInResults).intValue());
+        return parameterValue;
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a short.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a short value.
+     * @throws SQLException if param datatype is not SMALLINT
+     */
+    public short getShort(int parameterIndex) throws SQLException {
+        return DataTypeTransformer.getShort(getObject(parameterIndex));
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a String.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a String object.
+     * @throws SQLException if param datatype is not CHAR, VARCHAR, LONGVARCHAR
+     */
+    public String getString(int parameterIndex) throws SQLException {
+        // return the parameter value a String object
+       return getObject(parameterIndex).toString();
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Time object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a Time object.
+     * @throws SQLException if param datatype is not TIME
+     */
+    public Time getTime(int parameterIndex) throws SQLException {
+        return getTime(parameterIndex, null);
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Timestamp object. Calendar
+     * object contains the timezone information.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @param Calendar object used to construct the Date object.
+     * @return The parameter at the given index is returned as a Time object.
+     * @throws SQLException if param datatype is not TIME
+     */
+    public Time getTime(int parameterIndex, java.util.Calendar cal) throws SQLException {
+        Time value = DataTypeTransformer.getTime(getObject(parameterIndex));
+
+        if (value == null) {
+            return null;
+        }
+        
+        if (cal != null) {
+            value = TimestampWithTimezone.createTime(value, getDefaultCalendar().getTimeZone(), cal);
+        }
+        
+        return value;
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Timestamp object.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @return The parameter at the given index is returned as a Timestamp object.
+     * @throws SQLException if param datatype is not TIMESTAMP
+     */
+    public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+        return getTimestamp(parameterIndex, null);
+    }
+
+    /**
+     * <p>Gets the value of a OUTPUT parameter as a java.sql.Timestamp object. Calendar
+     * object contains the timezone information.
+     * @param parameterIndex whose value is to be fetched from the result.
+     * @param Calendar object used to construct the Date object.
+     * @return The parameter at the given index is returned as a Timestamp object.
+     * @throws SQLException if param datatype is not TIMESTAMP
+     */
+    public Timestamp getTimestamp(int parameterIndex, java.util.Calendar cal) throws SQLException {
+        Timestamp value = DataTypeTransformer.getTimestamp(getObject(parameterIndex));
+
+        if (value == null) {
+            return null;
+        }
+        
+        if (cal != null) {
+            value = TimestampWithTimezone.createTimestamp(value, getDefaultCalendar().getTimeZone(), cal);
+        }
+        
+        return value;
+    }
+
+    /**
+     * <p>Register the OUT parameter in the ordinal position parameterIndex to jdbcsql
+     * type. Scale is used by setXXX methods to determine number of decimals.
+     * @param parameterIndex. Index of the OUT parameter in the stored procedure.
+     * @param jdbcSqlType. SQL type codes from java.sql.Types
+     * @param SQLException, should never occur
+     */
+    public void registerOutParameter(int parameterIndex, int jdbcSqlType) throws SQLException {
+        // ignore - we don't care
+    }
+
+    /**
+     * <p>Register the OUT parameter in the ordinal position parameterIndex to jdbcsql
+     * type. Scale is used by setXXX methods to determine number of decimals.
+     * @param parameterIndex. Index of the OUT parameter in the stored procedure.
+     * @param jdbcSqlType. SQL type codes from java.sql.Types
+     * @param scale. The number of decimal digits on the OUT param.
+     * @param SQLException, should never occur
+     */
+    public void registerOutParameter(int parameterIndex, int jdbcSqlType, int scale) throws SQLException {
+        // ignore - we don't care
+    }
+
+    /**
+     * <p>Register the OUT parameter in the ordinal position parameterIndex to jdbcsql
+     * type. The param typename(SQL name for user-named type) is ignored as SQL3
+     * datatypes are not supported.
+     * @param parameterIndex. Index of the OUT parameter in the stored procedure.
+     * @param jdbcSqlType. SQL type codes from java.sql.Types
+     * @param typeName. SQL name of user-named type being used
+     * @param SQLException, should never occur
+     */
+    public void registerOutParameter (int parameterIndex, int jdbcSqlType, String typeName) throws SQLException {
+        // ignore - we don't care
+    }
+   
+    /**
+     * <p>Indicates whether the last OUT parameter read was a return null.
+     * @return true if the last param read was null else false.
+     * @throws SQLException, if the statement is already closed.
+     */
+    public boolean wasNull() throws SQLException {
+        checkStatement();
+
+        return parameterValue == null;
+    }
+
+	public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+		return DataTypeTransformer.getSQLXML(getObject(parameterIndex));
+	}
+
+	public Array getArray(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Array getArray(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Blob getBlob(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	
+	public boolean getBoolean(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public byte getByte(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public byte[] getBytes(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public byte[] getBytes(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Reader getCharacterStream(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Reader getCharacterStream(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Clob getClob(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Date getDate(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Date getDate(String parameterName, Calendar cal) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public double getDouble(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public float getFloat(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public int getInt(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public long getLong(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Reader getNCharacterStream(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public NClob getNClob(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	//## JDBC4.0-begin ##
+	public NClob getNClob(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public String getNString(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public String getNString(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Object getObject(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Object getObject(int parameterIndex, Map<String, Class<?>> map) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Object getObject(String parameterName, Map<String, Class<?>> map) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Ref getRef(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Ref getRef(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##    
+	public RowId getRowId(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+    //## JDBC4.0-end ##
+
+	//## JDBC4.0-begin ##
+	public RowId getRowId(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+	
+	public SQLXML getSQLXML(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public short getShort(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public String getString(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Time getTime(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Time getTime(String parameterName, Calendar cal) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Timestamp getTimestamp(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public URL getURL(int parameterIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public URL getURL(String parameterName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void registerOutParameter(String parameterName, int sqlType)	throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void registerOutParameter(String parameterName, int sqlType,int scale) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void registerOutParameter(String parameterName, int sqlType,	String typeName) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setAsciiStream(String parameterName, InputStream x)	throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setAsciiStream(String parameterName, InputStream x, int length)	throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBinaryStream(String parameterName, InputStream x, int length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBinaryStream(String parameterName, InputStream x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBlob(String parameterName, Blob x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBlob(String parameterName, InputStream inputStream)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBlob(String parameterName, InputStream inputStream,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBoolean(String parameterName, boolean x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setByte(String parameterName, byte x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBytes(String parameterName, byte[] x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setCharacterStream(String parameterName, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	}
+
+	public void setCharacterStream(String parameterName, Reader reader,
+			int length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setCharacterStream(String parameterName, Reader reader,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setClob(String parameterName, Clob x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setClob(String parameterName, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setClob(String parameterName, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setDate(String parameterName, Date x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setDate(String parameterName, Date x, Calendar cal)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setDouble(String parameterName, double x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setFloat(String parameterName, float x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setInt(String parameterName, int x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setLong(String parameterName, long x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNCharacterStream(String parameterName, Reader value)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNCharacterStream(String parameterName, Reader value,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public void setNClob(String parameterName, NClob value) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void setNClob(String parameterName, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNClob(String parameterName, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNString(String parameterName, String value)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNull(String parameterName, int sqlType) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}		
+
+	public void setNull(String parameterName, int sqlType, String typeName)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setObject(String parameterName, Object x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setObject(String parameterName, Object x, int targetSqlType)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setObject(String parameterName, Object x, int targetSqlType,
+			int scale) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public void setRowId(String parameterName, RowId x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void setSQLXML(String parameterName, SQLXML xmlObject)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+
+	public void setShort(String parameterName, short x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setString(String parameterName, String x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setTime(String parameterName, Time x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setTime(String parameterName, Time x, Calendar cal)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setTimestamp(String parameterName, Timestamp x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setTimestamp(String parameterName, Timestamp x, Calendar cal)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setURL(String parameterName, URL val) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+}
\ No newline at end of file

Copied: trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ConnectionImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,1000 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+//## JDBC4.0-begin ##
+import java.sql.SQLClientInfoException;
+import java.sql.NClob;
+import java.sql.SQLXML;
+//## JDBC4.0-end ##
+
+/*## JDBC3.0-JDK1.5-begin ##
+import com.metamatrix.core.jdbc.SQLXML; 
+## JDBC3.0-JDK1.5-end ##*/
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.transaction.xa.Xid;
+
+import org.teiid.client.DQP;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.net.CommunicationException;
+import org.teiid.net.TeiidURL;
+import org.teiid.net.ServerConnection;
+import org.teiid.net.socket.SocketServerConnection;
+
+
+
+import com.metamatrix.common.util.SqlUtil;
+
+public class ConnectionImpl extends WrapperImpl implements Connection {
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+
+	// constant value giving product name
+    private final static String SERVER_NAME = "Teiid Server"; //$NON-NLS-1$
+    private final static String EMBEDDED_NAME = "Teiid Embedded"; //$NON-NLS-1$
+
+    // Unique request ID generator
+    private long requestIDGenerator;
+
+    // url used to create the connection
+    private String url;
+ 
+    // properties object containing the connection properties.
+    protected Properties propInfo;
+
+    // status of connection object
+    private boolean closed = false;
+    // determines if a statement executed should be immediately committed.
+    private boolean autoCommitFlag = true;
+
+    // collection of all open statements on this connection
+    private Collection<StatementImpl> statements = new ArrayList<StatementImpl>();
+    // cached DatabaseMetadata
+    private DatabaseMetaData dbmm;
+
+   //Xid for participating in TXN
+    private XidImpl transactionXid;
+            
+    //  Flag to represent if the connection state needs to be readOnly, default value false.
+    private boolean readOnly = false;
+    
+    private boolean disableLocalTransactions = false;
+    private DQP dqp;
+    protected ServerConnection serverConn;
+    private int transactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
+        
+    public ConnectionImpl(ServerConnection serverConn, Properties info, String url) {        
+    	this.serverConn = serverConn;
+        this.url = url;
+        this.dqp = serverConn.getService(DQP.class);
+        
+        // set default properties if not overridden
+        String overrideProp = info.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP);
+        if ( overrideProp == null || overrideProp.trim().length() == 0 ) {
+            info.put(ExecutionProperties.PROP_TXN_AUTO_WRAP, ExecutionProperties.TXN_WRAP_DETECT);
+        }
+
+        // Get default fetch size
+        String defaultFetchSize = info.getProperty(ExecutionProperties.PROP_FETCH_SIZE);
+        if (defaultFetchSize != null) {
+            info.put(ExecutionProperties.PROP_FETCH_SIZE, defaultFetchSize);
+        } else {
+            info.put(ExecutionProperties.PROP_FETCH_SIZE, ""+BaseDataSource.DEFAULT_FETCH_SIZE); //$NON-NLS-1$
+        }
+
+        // Get partial results mode
+        String partialResultsMode = info.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE);
+        if (partialResultsMode != null) {
+            info.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, partialResultsMode);
+        } else {
+            info.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, BaseDataSource.DEFAULT_PARTIAL_RESULTS_MODE);
+        }
+        
+        // Get result set cache mode
+        String resultSetCacheMode = info.getProperty(ExecutionProperties.RESULT_SET_CACHE_MODE);
+        if (resultSetCacheMode != null) {
+            info.put(ExecutionProperties.RESULT_SET_CACHE_MODE, resultSetCacheMode);
+        } else {
+            info.put(ExecutionProperties.RESULT_SET_CACHE_MODE, BaseDataSource.DEFAULT_RESULT_SET_CACHE_MODE);
+        }
+
+        String ansiQuotes = info.getProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS);
+        if (ansiQuotes != null) {
+            info.put(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS, ansiQuotes);
+        } else {
+            info.put(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS, Boolean.TRUE.toString());
+        }
+                
+        logger.fine(JDBCPlugin.Util.getString("MMConnection.Session_success")); //$NON-NLS-1$
+        logConnectionProperties(url, info);
+                
+        // properties object used in obtaining connection
+        this.propInfo = info;
+        
+        this.disableLocalTransactions = Boolean.valueOf(this.propInfo.getProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS)).booleanValue();
+    }
+    
+    protected Properties getConnectionProperties() {
+        return this.propInfo;
+    }
+    
+    DQP getDQP() {
+    	return this.dqp;
+    }
+    
+    /**
+     * Remove password & trusted token and log all other properties
+     * @param connUrl - URL used to connect to server
+     * @param info - properties object supplied
+     */
+    private void logConnectionProperties(String connUrl, Properties info) {
+        StringBuffer modifiedUrl = new StringBuffer();
+
+        // If we have valid URL
+        if (connUrl != null) {
+	        // We need wipe out the password here, before we write to the log
+	        int startIndex = connUrl.indexOf("password="); //$NON-NLS-1$
+	        if (startIndex != -1) {
+	            modifiedUrl.append(connUrl.substring(0, startIndex));
+	            modifiedUrl.append("password=***"); //$NON-NLS-1$
+	            int endIndex = connUrl.indexOf(";", startIndex+9); //$NON-NLS-1$
+	            if (endIndex != -1) {
+	                modifiedUrl.append(";").append(connUrl.substring(endIndex)); //$NON-NLS-1$
+	            }
+	        }
+	        logger.fine("Connection Url="+modifiedUrl); //$NON-NLS-1$
+        }
+        
+        // Now clone the properties object and remove password and trusted token
+        if (info != null) {
+            Enumeration enumeration = info.keys();
+            while (enumeration.hasMoreElements()) {
+                String key = (String)enumeration.nextElement();
+                Object anObj = info.get(key);
+                // Log each property except for password and token.
+                if (!TeiidURL.CONNECTION.PASSWORD.equalsIgnoreCase(key)) { 
+                    logger.fine(key+"="+anObj); //$NON-NLS-1$
+                }
+            }
+        }                              
+    }
+        
+    String getUrl() {
+        return this.url;
+    }
+    
+    /**
+     * Connection identifier of this connection 
+     * @return identifier
+     * @throws SQLException 
+     */
+    public String getConnectionId() {
+    	return String.valueOf(this.serverConn.getLogonResult().getSessionID());
+    }
+    
+    long currentRequestId() {
+        return requestIDGenerator;
+    }
+    
+    /**
+     * Generate the next unique requestID for matching up requests with responses.
+     * These IDs should be unique only in the context of a ServerConnection instance.
+     * @return Request ID
+     */
+    long nextRequestID() {
+        return requestIDGenerator++;
+    }
+
+    public void clearWarnings() throws SQLException {
+        // do nothing
+    }
+
+    public void close() throws SQLException {
+    	Throwable firstException = null;
+
+    	if(closed) {
+            return;
+        }
+
+        try {
+            // close any statements that were created on this connection
+        	try {
+        		closeStatements();
+        	} catch (SQLException se) {
+        		firstException = se;
+        	} finally {
+        		this.serverConn.close();
+                if ( firstException != null )
+                	throw (SQLException)firstException;
+        	}
+        } catch (SQLException se) {
+            throw TeiidSQLException.create(se, JDBCPlugin.Util.getString("MMConnection.Err_connection_close", se.getMessage())); //$NON-NLS-1$
+        } finally {
+            logger.fine(JDBCPlugin.Util.getString("MMConnection.Connection_close_success")); //$NON-NLS-1$
+            // set the status of the connection to closed
+            closed = true;            
+        }
+    }
+
+    /**
+     * <p>
+     * Close all the statements open on this connection
+     * </p>
+     * 
+     * @throws SQLException
+     *             server statement object could not be closed.
+     */
+    void closeStatements() throws SQLException {
+        // Closing the statement will cause the
+        // MMConnection.closeStatement() method to be called,
+        // which will modify this.statements.  So, we do this iteration
+        // in a separate safe copy of the list
+        List statementsSafe = new ArrayList(this.statements);
+        Iterator statementIter = statementsSafe.iterator();
+        SQLException ex = null;
+        while (statementIter.hasNext ()) {
+            Statement statement = (Statement) statementIter.next();
+            try {
+            	statement.close();
+            } catch (SQLException e) {
+            	ex = e;
+            }
+        }
+        if (ex != null) {
+            throw TeiidSQLException.create(ex, JDBCPlugin.Util.getString("MMConnection.Err_closing_stmts")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Called by MMStatement to notify the connection that the
+     * statement has been closed.
+     * @param statement
+     */
+    void closeStatement(Statement statement) {
+        this.statements.remove(statement);
+    }
+
+    /**
+     * <p>This method makes any changes involved in a transaction permanent and releases
+     * any locks held by the connection object.  This is only used when auto-commit
+     * is set to false.</p>
+     * @throws SQLException if the transaction had been rolled back or marked to roll back.
+     */
+    public void commit() throws SQLException {
+        checkConnection();
+        if (!autoCommitFlag) {
+            try {
+                directCommit();
+            } finally {
+                beginLocalTxn(); 
+            }
+        }
+    }
+
+    private void directCommit() throws SQLException {
+        try {
+			ResultsFuture<?> future = this.dqp.commit();
+			future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+        logger.fine(JDBCPlugin.Util.getString("MMConnection.Commit_success")); //$NON-NLS-1$
+    }
+
+    private void beginLocalTxn() throws SQLException {
+        if (this.transactionXid == null) {
+        	if (disableLocalTransactions) {
+        		this.autoCommitFlag = true;
+        		return;
+        	}
+            boolean txnStarted = false;
+            try {
+            	try {
+            		this.dqp.begin();
+        		} catch (XATransactionException e) {
+        			throw TeiidSQLException.create(e);
+        		} 
+                txnStarted = true;
+            } finally {
+                if (!txnStarted) {
+                    autoCommitFlag = true;
+                }
+            }
+        }
+    }
+    
+    /**
+     * <p>This creates a MMStatement object for sending SQL statements to the MetaMatrix
+     * server.  This should be used for statements without parameters.  For statements
+     * that are executed many times, use the PreparedStatement object.</p>
+     * @return a Statement object.
+     * @throws a SQLException if a MetaMatrix server access error occurs.
+     */
+    public Statement createStatement() throws SQLException {
+        return createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+    }
+
+    /**
+     * <p>Creates a Statement object that will produce ResultSet objects of the type
+     * resultSetType and concurrency level resultSetConcurrency.</p>
+     * @param intvalue indicating the ResultSet's type
+     * @param intValue indicating the ResultSet's concurrency
+     * @return Statement object.
+     */
+    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+
+        validateResultSetType(resultSetType);
+        validateResultSetConcurrency(resultSetConcurrency);
+
+        // add the statement object to the map
+        StatementImpl newStatement = StatementImpl.newInstance(this, resultSetType, resultSetConcurrency);
+        statements.add(newStatement);
+
+        return newStatement;
+    }
+
+    /** 
+     * @param resultSetType
+     * @throws TeiidSQLException
+     * @since 4.3
+     */
+    private void validateResultSetType(int resultSetType) throws TeiidSQLException {
+        if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE ) {
+            String msg = JDBCPlugin.Util.getString("MMConnection.Scrollable_type_not_supported", "ResultSet.TYPE_SCROLL_SENSITIVE"); //$NON-NLS-1$ //$NON-NLS-2$
+            throw new TeiidSQLException(msg);
+        }
+    }
+
+    /** 
+     * @param resultSetConcurrency
+     * @throws TeiidSQLException
+     * @since 4.3
+     */
+    private void validateResultSetConcurrency(int resultSetConcurrency) throws TeiidSQLException {
+        if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) {
+            String msg = JDBCPlugin.Util.getString("MMConnection.Concurrency_type_not_supported", "ResultSet.CONCUR_UPDATABLE"); //$NON-NLS-1$ //$NON-NLS-2$
+            throw new TeiidSQLException(msg);
+        }
+    }
+
+    /**
+     * <p>This method returns the current status of the connection in regards to it's
+     * auto-commit state.  By default, the auto-commit is set to true.  Meaning that
+     * any transaction that occurs is automatically commited to the MetaMatrix server.
+     * #See corresponding setAutoCommit() method.</p>
+     * @return true if the statements on this connection get committed on execution.
+     * @throws SQLException should never happen
+     */
+    public boolean getAutoCommit() throws SQLException {
+        //Check to see the connection is open
+       checkConnection();
+       return autoCommitFlag;
+    }
+
+    public String getCatalog() throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        //catalogs are not supported
+        return this.serverConn.getLogonResult().getVdbName();
+    }
+
+    /**
+     * <p>This method gets the ServerConnection object wrapped by this object.</p>
+     * @return ServerConnection object
+     */
+    ServerConnection getServerConnection() throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        return serverConn;
+    }
+
+    String getVDBName() throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        //get the virtual database name to which we are connected.
+
+        return this.serverConn.getLogonResult().getVdbName();
+    }
+    
+    public int getVDBVersion() throws SQLException {
+    	checkConnection();
+        return this.serverConn.getLogonResult().getVdbVersion();
+    }
+
+    /**
+     * Get's the name of the user who got this connection.
+     * @return Sring object giving the user name
+     * @throws SQLException if the connection is closed
+     */
+    String getUserName() throws SQLException {
+        checkConnection();
+
+        return this.serverConn.getLogonResult().getUserName();
+    }
+    
+    public DatabaseMetaData getMetaData() throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        
+        if (dbmm == null) {
+            dbmm = new DatabaseMetaDataImpl(this);
+        }       
+        return dbmm;
+    }
+
+    /**
+     * Get the database name that this connection is representing 
+     * @return String name of the database
+     */
+    public String getDatabaseName() {
+    	if (this.serverConn instanceof SocketServerConnection) {
+    		return SERVER_NAME;
+    	}
+    	return EMBEDDED_NAME;
+    }
+    
+    /**
+     * Retrieves the current holdability of ResultSet objects created using this Connection object.
+     * @param holdability int indicating the holdability
+     * @return int holdability
+     * @throws SQLException
+     */
+    public int getHoldability() throws SQLException {
+        return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+    }
+
+    public int getTransactionIsolation() throws SQLException {
+    	return this.transactionIsolation;
+    }
+
+    /**
+     * Retreives the type map associated with this Connection object. The type map
+     * contains entries for undefined types. This method always returns an empty
+     * map since it is not possible to add entries to this type map
+     * @return map containing undefined types(empty)
+     * @throws SQLException, should never occur
+     */
+    public Map getTypeMap() throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        return new HashMap();
+    }
+
+    /**
+     * <p>This method will return the first warning reported by calls on this connection,
+     * or null if none exist.</p>
+     * @return A SQLWarning object if there are any warnings.
+     * @throws SQLException, should never occur
+     */
+    public SQLWarning getWarnings() throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        return null;  // we don't have any warnings
+    }
+
+    /**
+     * <p>This method will return whether this connection is closed or not.</p>
+     * @return booleanvalue indicating if the connection is closed
+     * @throws SQLException, should never occur
+     */
+    public boolean isClosed() throws SQLException {
+        return closed;
+    }
+
+    /**
+     * <p>This method will return whether this connection is read only or not.
+     * It will throw a SQLException if a MetaMatrix server access error occurs.
+     * @return boolean value indication if connection is readonly
+     * @throws SQLException, should never occur
+     */
+    public boolean isReadOnly() throws SQLException {
+         return readOnly; 
+    }
+
+    /**
+     * <p>This method will convert the given SQL String into a MetaMatrix SQL Request.
+     * This will convert any date escape sequences into the appropriate MetaMatrix
+     * type, and any kind of data transformations that the MetaMatrix server would
+     * expect.  This method returns the native form of the statement that the driver
+     * would have sent.</p>
+     * @param sql string to be coverted into SQL understood by metamatrix
+     * @return uncoverted sql string(escape parsing takesplace in metamatrix)
+     * @throws SQLException, should never occur
+     */
+    public String nativeSQL(String sql) throws SQLException {
+        // return the string argument without any modifications.
+        // escape syntaxes are directly supported in the server
+        return sql;
+    }
+
+    /**
+     * <p>Creates a CallableStatement object that contains sql and that will produce
+     * ResultSet objects that are non-scrollable and non-updatable. A SQL stored
+     * procedure call statement is handled by creating a CallableStatement for it.</p>
+     * @param sql String(escape syntax) for invoking a stored procedure.
+     * @return CallableStatement object that can be used to execute the storedProcedure
+     * @throws SQLException if there is an error creating the callable statement object
+     */
+    public CallableStatement prepareCall(String sql) throws SQLException {
+    	//there is a problem setting the result set type to be non-scrollable
+    	//See defect 17768
+        return prepareCall(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    }
+
+    /**
+     * <p>Creates a CallableStatement object that contains a sql and that will produce
+     * ResultSet objects of the type resultSetType and with a concurrency level of
+     * resultSetConcurrency. A SQL stored procedure call statement is handled by
+     * creating a CallableStatement for it.</p>
+     * @param sql String(escape syntax) for invoking a stored procedure.
+     * @param intvalue indicating the ResultSet's type
+     * @param intValue indicating the ResultSet's concurrency
+     * @return CallableStatement object that can be used to execute the storedProcedure
+     */
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        
+        validateResultSetType(resultSetType);
+        validateResultSetConcurrency(resultSetConcurrency);
+        validateSQL(sql);
+        
+        // add the statement object to the map
+        CallableStatementImpl newStatement = CallableStatementImpl.newInstance(this, sql, resultSetType, resultSetConcurrency);
+        statements.add(newStatement);
+        return newStatement;
+    }
+
+    /** 
+     * @param sql
+     * @throws TeiidSQLException
+     * @since 4.3
+     */
+    private void validateSQL(String sql) throws TeiidSQLException {
+        if (sql == null) {
+            String msg = JDBCPlugin.Util.getString("MMConnection.SQL_cannot_be_null"); //$NON-NLS-1$
+            throw new TeiidSQLException(msg);
+        }
+    }
+
+    /**
+     * <p>This method creates a MMPreparedStatement which is used for sending parameterized
+     * SQL statements to the MetaMatrix server.  A statement with or without IN parameters
+     * can be pre-compiled and stored in a MMPreparedStatement object.  Since the MetaMatrix
+     * server does not pre-compile statements, a sql statement will be constructed using the
+     * parameters supplied which would be used for execution of this preparedStatement object.</p>
+     * @param sql string representing a prepared statement
+     * @return a PreparedStatement object
+     * @throws SQLException if there is an error creating a prepared statement object
+     */
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+        return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+    }
+
+    /**
+     * <p>Creates a PreparedStatement object that contains a sql and that will produce
+     * ResultSet objects of the type resultSetType and with a concurrency level of
+     * resultSetConcurrency.</p>
+     * @param sql string representing a prepared statement
+     * @param intvalue indicating the ResultSet's type
+     * @param intValue indicating the ResultSet's concurrency
+     * @return a PreparedStatement object
+     */
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+        
+        validateResultSetType(resultSetType);
+        validateResultSetConcurrency(resultSetConcurrency);
+        validateSQL(sql);
+        
+        // add the statement object to the map
+        PreparedStatementImpl newStatement = PreparedStatementImpl.newInstance(this, sql, resultSetType, resultSetConcurrency);
+        statements.add(newStatement);
+        return newStatement;
+    }
+
+    /**
+     * <p>This method creates a MMPreparedStatement which is used for sending parameterized
+     * SQL statements to the MetaMatrix server and it has the capability to retrieve auto-generated keys.</p>
+     * @param sql string representing a prepared statement
+     * @param intValue indicating the result set Type
+     * @param intValue indicating the result set concurrency
+     * @param intValue indicating the result set holdability
+     * @return a PreparedStatement object
+     * @throws SQLException if there is an error creating a prepared statement object
+     */
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+        int resultSetHoldability ) throws SQLException {
+    	throw SqlUtil.createFeatureNotSupportedException();
+    }
+
+    /**
+     * <p>This method will drop all changes made since the beginning of the transaction
+     * and release any MetaMatrix server locks currently held by this connection. This
+     * method rolls back transactions on all the statements currently open on this connection.
+     * This is used when then auto-commit has been disabled.</p>
+     * @see setAutoCommit(boolean) method for more information.
+     * @throws SQLException if there is an error rolling back.
+     */
+    public void rollback() throws SQLException {
+        rollback(true);
+    }
+    
+    void rollback(boolean startTxn) throws SQLException {
+
+        //Check to see the connection is open
+        checkConnection();
+        if (!autoCommitFlag) {
+            try {
+            	try {
+            		ResultsFuture<?> future = this.dqp.rollback();
+            		future.get();
+        		} catch (Exception e) {
+        			throw TeiidSQLException.create(e);
+        		}
+                logger.fine(JDBCPlugin.Util.getString("MMConnection.Rollback_success")); //$NON-NLS-1$
+            } finally {
+                if (startTxn) {
+                    beginLocalTxn();
+                }
+                else {
+                    this.autoCommitFlag = true;
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>This method will set the connection's auto commit mode accordingly.  By
+     * default this is set to true (auto-commit is turned on).  An auto-commit
+     * value of true means any statements will automatically be made permanent if
+     * they are successful after the last row of the ReulstSet has been retrieved
+     * or the next execute occurs, whichever comes first.  If set to false, changes
+     * can be either be committed (using the commit() method) or rolled back ("undo
+     * the changes" by using the rollback() method).</p>
+     * @param boolean value indicating if autoCommit is turned on
+     * @throws SQLException is metamatrix access error occurs.
+     */
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        //Check to see the connection is open
+        checkConnection();
+
+        if (autoCommit == this.autoCommitFlag) {
+            return;
+        }
+        
+        this.autoCommitFlag = autoCommit;
+
+        if (autoCommit) {
+            directCommit();   
+        } else {
+            beginLocalTxn();
+        }        
+    }
+
+    /**
+     * <p>Metamatrix does not allow setting a catalog through a connection. This
+     * method silently ignores the request as per the specification.</p>
+     * @param The string values which sets the catalog name on the connection.
+     * @throws SQLException This should never occur.
+     */
+    public void setCatalog(String catalog) throws SQLException {
+        // do nothing, silently ignore the request
+    }
+
+    /**
+     * @param A boolean value specifying whether the connection is readonly.
+     * @throws throws SQLException.
+     */
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        if (this.readOnly == readOnly) {
+            return;
+        }
+        // During transaction do not allow to change this flag
+        if (!autoCommitFlag || this.transactionXid != null) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Invalid_During_Transaction", "setReadOnly(" + readOnly + ")"));//$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+        }
+        this.readOnly = readOnly;
+    }
+
+    /**
+     * <p> This utility method checks if the jdbc connection is closed and
+     * throws an exception if it is closed. </p>
+     * @throws SQLException if the connection object is closed.
+     */
+    void checkConnection() throws SQLException{
+        //Check to see the connection is closed and proceed if it is not
+       if (closed) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMConnection.Cant_use_closed_connection")); //$NON-NLS-1$
+        }
+     }
+
+    protected void commitTransaction(XidImpl arg0, boolean arg1) throws SQLException {
+        checkConnection();
+        transactionXid = null;
+        this.autoCommitFlag = true;
+        try {
+        	ResultsFuture<?> future = this.dqp.commit(arg0, arg1);
+        	future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    protected void endTransaction(XidImpl arg0, int arg1) throws SQLException {
+        checkConnection();
+        this.autoCommitFlag = true;
+        try {
+        	ResultsFuture<?> future = this.dqp.end(arg0, arg1);
+        	future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    protected void forgetTransaction(XidImpl arg0) throws SQLException {
+        checkConnection();
+        try {
+        	ResultsFuture<?> future = this.dqp.forget(arg0);
+        	future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    protected int prepareTransaction(XidImpl arg0) throws SQLException  {
+        checkConnection();
+        transactionXid = null;
+        try {
+        	ResultsFuture<Integer> future = this.dqp.prepare(arg0);
+        	return future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    protected Xid[] recoverTransaction(int arg0) throws SQLException  {
+        checkConnection();
+        try {
+			ResultsFuture<Xid[]> future = this.dqp.recover(arg0);
+			return future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    protected void rollbackTransaction(XidImpl arg0) throws SQLException {
+        checkConnection();
+        transactionXid = null;
+        this.autoCommitFlag = true;
+        try {
+        	ResultsFuture<?> future = this.dqp.rollback(arg0);
+        	future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    protected void startTransaction(XidImpl arg0, int arg1, int timeout) throws SQLException {
+        checkConnection();
+        try {
+        	ResultsFuture<?> future = this.dqp.start(arg0, arg1, timeout);
+        	future.get();
+		} catch (Exception e) {
+			throw TeiidSQLException.create(e);
+		}
+        transactionXid = arg0;
+        this.autoCommitFlag = false;
+    }
+
+    protected XidImpl getTransactionXid() {
+        return transactionXid;
+    }
+    
+	public boolean isValid(int timeout) throws SQLException {
+		Statement statement = null;
+		try {
+			statement = createStatement();
+			statement.setQueryTimeout(timeout);
+			statement.execute("select 1"); //$NON-NLS-1$
+			return true;
+		} catch (SQLException e) {
+			return false;
+		} finally {
+			if (statement != null) {
+				try {
+					statement.close();
+				} catch (SQLException e) {
+				}
+			}
+		}
+	}
+	
+	public void recycleConnection() {
+        try {
+        	//close all open statements
+        	this.closeStatements();
+        } catch (SQLException e) {
+            logger.log(Level.WARNING, JDBCPlugin.Util.getString("MMXAConnection.rolling_back_error"), e); //$NON-NLS-1$
+        }
+        try {
+            //rollback if still in a transaction
+            if (!this.getAutoCommit()) {
+                logger.warning(JDBCPlugin.Util.getString("MMXAConnection.rolling_back")); //$NON-NLS-1$
+                
+                if (this.getTransactionXid() == null) {
+                    this.rollback(false);
+                } else {
+                	this.rollbackTransaction(getTransactionXid());
+                }
+            }
+        } catch (SQLException e) {
+        	logger.log(Level.WARNING, JDBCPlugin.Util.getString("MMXAConnection.rolling_back_error"), e); //$NON-NLS-1$
+        }
+        
+		//perform load balancing
+		if (this.serverConn instanceof SocketServerConnection) {
+			((SocketServerConnection)this.serverConn).selectNewServerInstance(this.getDQP());
+		}
+	}
+	
+	public boolean isSameProcess(ConnectionImpl conn) throws CommunicationException {
+		return this.serverConn.isSameInstance(conn.serverConn);
+	}
+	
+	//## JDBC4.0-begin ##
+	public void setClientInfo(Properties properties)
+		throws SQLClientInfoException {
+	}
+
+	public void setClientInfo(String name, String value)
+		throws SQLClientInfoException {
+	}
+	//## JDBC4.0-end ##
+	
+	public Properties getClientInfo() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public String getClientInfo(String name) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Array createArrayOf(String typeName, Object[] elements)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Blob createBlob() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Clob createClob() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public NClob createNClob() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public SQLXML createSQLXML() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Statement createStatement(int resultSetType,
+			int resultSetConcurrency, int resultSetHoldability)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public Struct createStruct(String typeName, Object[] attributes)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public CallableStatement prepareCall(String sql, int resultSetType,
+			int resultSetConcurrency, int resultSetHoldability)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public PreparedStatement prepareStatement(String sql, String[] columnNames)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public void rollback(Savepoint savepoint) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+
+	}
+
+	public void setHoldability(int holdability) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Savepoint setSavepoint() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Savepoint setSavepoint(String name) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setTransactionIsolation(int level) throws SQLException {
+		this.transactionIsolation = level;
+	}
+
+	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ConnectionListener.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+
+/**
+ * A JDBC Connection lifecycle listener 
+ */
+public interface ConnectionListener {
+        
+    /**
+     * Called when a new connection is created.  
+     */
+    void connectionAdded(String id, Connection connection);
+
+    /**
+     * Called when a connection is closed. 
+     */
+    void connectionRemoved(String id, Connection connection);
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/DataTypeTransformer.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,270 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.SQLXML;
+//## JDBC4.0-end ##
+/*## JDBC3.0-JDK1.5-begin ##
+import com.metamatrix.core.jdbc.SQLXML; 
+## JDBC3.0-JDK1.5-end ##*/
+import java.sql.Time;
+import java.sql.Timestamp;
+
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.TransformationException;
+import com.metamatrix.common.types.DataTypeManager.DefaultDataClasses;
+
+/**
+ * <p>This class is used to transform objects into desired data types. The static
+ * method on this class are used by Metadatresults, ResultsWrapper and
+ * MMCallableStatement classes.</p>
+ */
+final class DataTypeTransformer {
+
+    // Prevent instantiation
+    private DataTypeTransformer() {}
+
+    /**
+     * Gets an object value and transforms it into a java.math.BigDecimal object.
+     * @param value, the object to be transformed
+     * @return a BigDecimal object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final BigDecimal getBigDecimal(Object value) throws SQLException {
+    	return transform(value, BigDecimal.class, "BigDecimal"); //$NON-NLS-1$
+    }
+    
+    private static final <T> T transform(Object value, Class<T> type, String typeName) throws SQLException {
+    	return transform(value, type, type, typeName);
+    }
+    
+    private static final <T> T transform(Object value, Class<T> targetType, Class<?> runtimeType, String typeName) throws SQLException {
+    	if (value == null || targetType.isAssignableFrom(value.getClass())) {
+    		return (T)value;
+    	}
+    	try {
+    		return (T)DataTypeManager.transformValue(DataTypeManager.convertToRuntimeType(value), runtimeType);
+    	} catch (TransformationException e) {
+    		String valueStr = value.toString();
+    		if (valueStr.length() > 20) {
+    			valueStr = valueStr.substring(0, 20) + "..."; //$NON-NLS-1$
+    		}
+    		String msg = JDBCPlugin.Util.getString("DataTypeTransformer.Err_converting", valueStr, typeName); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, msg);
+    	} 
+    }
+    
+    /**
+     * Gets an object value and transforms it into a boolean
+     * @param value, the object to be transformed
+     * @return a Boolean object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final boolean getBoolean(Object value) throws SQLException {
+    	if (value == null) {
+    		return false;
+    	}
+    	return transform(value, Boolean.class, "Boolean"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a byte
+     * @param value, the object to be transformed
+     * @return a Byte object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final byte getByte(Object value) throws SQLException {
+    	if (value == null) {
+    		return 0;
+    	}
+    	return transform(value, Byte.class, "Byte"); //$NON-NLS-1$
+    }
+    
+    static final byte[] getBytes(Object value) throws SQLException {
+        if (value == null) {
+            return null;
+        } else if (value instanceof byte[]) {
+        	return (byte[])value;
+        } else if (value instanceof Blob) {
+            Blob blob = (Blob)value;
+            long length = blob.length();
+            if (length > Integer.MAX_VALUE) {
+                throw new TeiidSQLException(JDBCPlugin.Util.getString("DataTypeTransformer.blob_too_big")); //$NON-NLS-1$
+            }
+            return blob.getBytes(1, (int)length);
+        } else if (value instanceof String) {
+        	return ((String)value).getBytes();
+        }
+        throw new TeiidSQLException(JDBCPlugin.Util.getString("DataTypeTransformer.cannot_get_bytes")); //$NON-NLS-1$
+    }
+    
+    static final Character getCharacter(Object value) throws SQLException {
+    	return transform(value, Character.class, "Character"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a java.sql.Date object.
+     * @param value, the object to be transformed
+     * @param Calendar object to be used to construct the Date object.
+     * @return a Date object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final Date getDate(Object value) throws SQLException {
+    	return transform(value, Date.class, "Date"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a double
+     * @param value, the object to be transformed
+     * @return a Double object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final double getDouble(Object value) throws SQLException {
+    	if (value == null) {
+    		return 0;
+    	}
+    	return transform(value, Double.class, "Double"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a float
+     * @param value, the object to be transformed
+     * @return a Float object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final float getFloat(Object value) throws SQLException {
+    	if (value == null) {
+    		return 0;
+    	}
+    	return transform(value, Float.class, "Float"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a integer
+     * @param value, the object to be transformed
+     * @return a Integer object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final int getInteger(Object value) throws SQLException {
+    	if (value == null) {
+    		return 0;
+    	}
+    	return transform(value, Integer.class, "Integer"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a long
+     * @param value, the object to be transformed
+     * @return a Long object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final long getLong(Object value) throws SQLException {
+    	if (value == null) {
+    		return 0;
+    	}
+    	return transform(value, Long.class, "Long"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a short
+     * @param value, the object to be transformed
+     * @return a Short object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final short getShort(Object value) throws SQLException {
+    	if (value == null) {
+    		return 0;
+    	}
+    	return transform(value, Short.class, "Short"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a java.sql.Time object.
+     * @param value, the object to be transformed
+     * @param Calendar object to be used to construct the Time object.
+     * @return a Time object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final Time getTime(Object value) throws SQLException {
+    	return transform(value, Time.class, "Time"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a java.sql.Timestamp object.
+     * @param value, the object to be transformed
+     * @param Calendar object to be used to construct the Timestamp object.
+     * @return a Timestamp object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final Timestamp getTimestamp(Object value) throws SQLException {
+    	return transform(value, Timestamp.class, "Timestamp"); //$NON-NLS-1$
+    }
+    
+    static final String getString(Object value) throws SQLException {
+    	if (value instanceof SQLXML) {
+    		return ((SQLXML)value).getString();
+    	} else if (value instanceof Clob) {
+    		Clob c = (Clob)value;
+    		return c.getSubString(1, c.length()>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)c.length());
+    	}
+    	return transform(value, String.class, "String"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a java.sql.Timestamp object.
+     * @param value, the object to be transformed
+     * @param Calendar object to be used to construct the Timestamp object.
+     * @return a Timestamp object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final Blob getBlob(Object value) throws SQLException {
+    	return transform(value, Blob.class, DefaultDataClasses.BLOB, "Blob"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a java.sql.Timestamp object.
+     * @param value, the object to be transformed
+     * @param Calendar object to be used to construct the Timestamp object.
+     * @return a Timestamp object
+     * @throws SQLException if failed to transform to the desired datatype
+     */
+    static final Clob getClob(Object value) throws SQLException {
+    	return transform(value, Clob.class, DefaultDataClasses.CLOB, "Clob"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets an object value and transforms it into a SQLXML object.
+     * @param value, the object to be transformed
+     * @return a SQLXML object
+     * @throws SQLException if failed to transform to the desired datatype
+     */    
+    static final SQLXML getSQLXML(Object value) throws SQLException {
+    	return transform(value, SQLXML.class, DefaultDataClasses.XML, "SQLXML"); //$NON-NLS-1$
+    }
+}
\ No newline at end of file

Copied: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,2963 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.metadata.ResultsMetadataConstants;
+import org.teiid.client.metadata.ResultsMetadataDefaults;
+
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.core.CoreConstants;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+
+public class DatabaseMetaDataImpl extends WrapperImpl implements DatabaseMetaData {
+	private static final String DATA_TYPES = "DataTypes"; //$NON-NLS-1$
+
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+        
+    /** CONSTANTS */
+    private static final String PERCENT = "%"; //$NON-NLS-1$    
+    // constant value indicating that there is not limit
+    private final static int NO_LIMIT = 0;
+    // constant value giving preferred name for a schema
+    private final static String SCHEMA_TERM = "Schema"; //$NON-NLS-1$
+    // constant value giving an empty string value
+    private final static String EMPTY_STRING = ""; //$NON-NLS-1$
+    // constant value giving a string used to escape search strings
+    private final static String ESCAPE_SEARCH_STRING = "\\"; //$NON-NLS-1$
+    // constant value giving an identifier quoting char
+    //private final static String SINGLE_QUOTE = "\'";
+    // constant value giving an identifier quoting string
+    private final static String DOUBLE_QUOTE = "\""; //$NON-NLS-1$
+    // constant value giving extra name characters used in Identifiers
+    private final static String EXTRA_CHARS = ".@"; //$NON-NLS-1$
+    // constant value giving the key words not in SQL-92
+    private final static String KEY_WORDS = "OPTION, SHOWPLAN, DEBUG"; //$NON-NLS-1$
+    // constant value giving preferred name for a procedure
+    private final static String PROCEDURE_TERM = "StoredProcedure"; //$NON-NLS-1$
+    // constant value giving the names of numeric functions supported
+    final static String NUMERIC_FUNCTIONS =
+        "ABS, ACOS, ASIN, ATAN, ATAN2, BITAND, BITNOT, BITOR, BITXOR, CEILING" //$NON-NLS-1$
+        + ", COS, COT, DEGREES, EXP, FLOOR, FORMATBIGDECIMAL, FORMATBIGINTEGER" //$NON-NLS-1$
+        + ", FORMATDOUBLE, FORMATFLOAT, FORMATINTEGER, FORMATLONG, LOG, LOG10" //$NON-NLS-1$
+        + ", MOD, PARSEBIGDECIMAL, PARSEBIGINTEGER, PARSEDOUBLE, PARSEFLOAT" //$NON-NLS-1$
+        + ", PARSEINTEGER, PARSELONG, PI, POWER, RADIANS, RAND, ROUND, SIGN, SIN, SQRT, TAN"; //$NON-NLS-1$
+    // constant value giving the names of string functions supported
+    final static String STRING_FUNCTIONS =
+        "ASCII, CHR, CHAR, CONCAT, CONCAT2, INITCAP, INSERT, LCASE, LEFT, LENGTH, LOCATE, LOWER, LPAD, LTRIM, " + //$NON-NLS-1$
+        "REPEAT, REPLACE, RIGHT, RPAD, RTRIM, SUBSTRING, TRANSLATE, UCASE, UPPER"; //$NON-NLS-1$
+    // constant value giving the names of date/time functions supported
+    final static String DATE_FUNCTIONS =
+        "CURDATE, CURTIME, NOW, DAYNAME, DAYOFMONTH, DAYOFWEEK, DAYOFYEAR, FORMATDATE, " + //$NON-NLS-1$
+        "FORMATTIME, FORMATTIMESTAMP, FROM_UNIXTIME, HOUR, MINUTE, MONTH, MONTHNAME, PARSEDATE, PARSETIME, " + //$NON-NLS-1$
+        "PARSETIMESTAMP, QUARTER, SECOND, TIMESTAMPADD, TIMESTAMPDIFF, WEEK, YEAR"; //$NON-NLS-1$
+    // constant value giving the names of system functions supported
+    final static String SYSTEM_FUNCTIONS =
+        "CAST, COALESCE, CONVERT, DECODESTRING, DECODEINTEGER, IFNULL, NULLIF, NVL, LOOKUP"; //$NON-NLS-1$
+    // constant value giving max length of a catalog name
+    private final static int MAX_CATALOG_NAME_LENGTH = 255;
+    // constant value giving max length of a procedure name
+    private final static int MAX_PROCEDURE_NAME_LENGTH = 255;
+    // constant value giving max length of a table name
+    private final static int MAX_TABLE_NAME_LENGTH = 255;
+    // constant value giving max length of a column name
+    private final static int MAX_COLUMN_NAME_LENGTH = 255;
+    // constant value giving max length of a user name
+    private final static int MAX_USER_NAME_LENGTH = 255;
+    // constant value giving min value of a columns scale
+    //private final static short MIN_SCALE = 0;
+    // constant value giving max value of a columns scale
+    //private final static short MAX_SCALE = 256;
+    
+    private final static String LIKE_ESCAPE = " LIKE ? ESCAPE '" + ESCAPE_SEARCH_STRING + "' ";//$NON-NLS-1$//$NON-NLS-2$
+    
+    final private static class RUNTIME_MODEL{
+        public final static String VIRTUAL_MODEL_NAME = CoreConstants.SYSTEM_MODEL;
+    }
+
+    private static final String TYPE_MAPPING;
+    
+    private static final String PRECISION_MAPPING;
+
+    static {
+        String[] internalTypes = MMJDBCSQLTypeInfo.getMMTypeNames();
+        StringBuffer typeMapping = new StringBuffer();
+        StringBuffer precisionMapping = new StringBuffer();
+        for (int i = 0; i < internalTypes.length; i++) {
+            if (i != 0) {
+                typeMapping.append(","); //$NON-NLS-1$
+                precisionMapping.append(","); //$NON-NLS-1$
+            }
+            typeMapping.append(internalTypes[i]).append(",").append(MMJDBCSQLTypeInfo.getSQLType(internalTypes[i])); //$NON-NLS-1$
+            precisionMapping.append(internalTypes[i]).append(",").append(ResultsMetadataDefaults.getDefaultPrecision(internalTypes[i])); //$NON-NLS-1$
+        }
+        TYPE_MAPPING = typeMapping.toString();
+        PRECISION_MAPPING = precisionMapping.toString();
+    }
+
+    private static final String NULLABILITY_MAPPING =
+        new StringBuffer("No Nulls, ").append(DatabaseMetaData.columnNoNulls) //$NON-NLS-1$
+          .append(     ", Nullable, ").append(DatabaseMetaData.columnNullable) //$NON-NLS-1$
+          .append(     ", Unknown, ") .append(DatabaseMetaData.columnNullableUnknown) //$NON-NLS-1$
+          .toString();
+      
+    private static final String PROC_COLUMN_NULLABILITY_MAPPING =
+        new StringBuffer("No Nulls, ").append(DatabaseMetaData.procedureNoNulls) //$NON-NLS-1$
+          .append(     ", Nullable, ").append(DatabaseMetaData.procedureNullable) //$NON-NLS-1$
+          .append(     ", Unknown, ") .append(DatabaseMetaData.procedureNullableUnknown) //$NON-NLS-1$
+          .toString();
+      
+    private static final String PARAM_DIRECTION_MAPPING = 
+      new StringBuffer("In,")         .append(DatabaseMetaData.procedureColumnIn) //$NON-NLS-1$
+      .append(       ", Out,")        .append(DatabaseMetaData.procedureColumnOut) //$NON-NLS-1$
+      .append(       ", InOut,")      .append(DatabaseMetaData.procedureColumnInOut) //$NON-NLS-1$
+      .append(       ", ReturnValue,").append(DatabaseMetaData.procedureColumnReturn) //$NON-NLS-1$
+      .append(       ", ResultSet,")  .append(DatabaseMetaData.procedureColumnResult) //$NON-NLS-1$
+      .toString();
+    
+//    private static final String UDT_NAME_MAPPING =
+//      new StringBuffer("JAVA_OBJECT, ").append(Types.JAVA_OBJECT) //$NON-NLS-1$
+//        .append(     ", DISTINCT, ")   .append(Types.DISTINCT) //$NON-NLS-1$
+//        .append(     ", STRUCT, ")     .append(Types.STRUCT) //$NON-NLS-1$
+//        .append(     ", null, ")       .append(Types.JAVA_OBJECT).toString(); //$NON-NLS-1$
+    
+    private static final String DATATYPES_WITH_NO_PRECISION =
+      new StringBuffer("'").append(DataTypeManager.DefaultDataTypes.STRING).append("', '") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(DataTypeManager.DefaultDataTypes.CHAR).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.CLOB).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.BLOB).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.BOOLEAN).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.DATE).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.TIME).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.TIMESTAMP).append("', '") //$NON-NLS-1$
+        .append(DataTypeManager.DefaultDataTypes.OBJECT).append("'").toString(); //$NON-NLS-1$
+
+    // Queries
+    private final static String QUERY_REFERENCE_KEYS =
+      new StringBuffer("SELECT PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, PKCOLUMN_NAME, FKTABLE_CAT, FKTABLE_SCHEM") //$NON-NLS-1$
+        .append(", FKTABLE_NAME, FKCOLUMN_NAME, KEY_SEQ, UPDATE_RULE, DELETE_RULE, FK_NAME, PK_NAME, DEFERRABILITY FROM ") //$NON-NLS-1$
+        .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".ReferenceKeyColumns").toString(); //$NON-NLS-1$
+    
+    private final static String QUERY_CROSS_REFERENCES = new StringBuffer(QUERY_REFERENCE_KEYS)
+    	.append(" WHERE UCASE(PKTABLE_CAT)").append(LIKE_ESCAPE).append("AND UCASE(FKTABLE_CAT)").append(LIKE_ESCAPE) //$NON-NLS-1$//$NON-NLS-2$
+    	.append(" AND UCASE(PKTABLE_SCHEM)").append(LIKE_ESCAPE).append("AND UCASE(FKTABLE_SCHEM)").append(LIKE_ESCAPE) //$NON-NLS-1$//$NON-NLS-2$
+        .append(" AND UCASE(PKTABLE_NAME)").append(LIKE_ESCAPE).append("AND UCASE(FKTABLE_NAME)").append(LIKE_ESCAPE) //$NON-NLS-1$//$NON-NLS-2$
+        .append("ORDER BY FKTABLE_NAME, KEY_SEQ").toString(); //$NON-NLS-1$ 
+    
+    private final static String QUERY_EXPORTED_KEYS = new StringBuffer(QUERY_REFERENCE_KEYS)
+	    .append(" WHERE UCASE(PKTABLE_CAT)").append(LIKE_ESCAPE) //$NON-NLS-1$
+		.append(" AND UCASE(PKTABLE_SCHEM)").append(LIKE_ESCAPE) //$NON-NLS-1$    
+	    .append(" AND UCASE(PKTABLE_NAME)").append(LIKE_ESCAPE).append("ORDER BY FKTABLE_NAME, KEY_SEQ").toString(); //$NON-NLS-1$//$NON-NLS-2$
+	    
+    private final static String QUERY_IMPORTED_KEYS = new StringBuffer(QUERY_REFERENCE_KEYS)
+    	.append(" WHERE UCASE(FKTABLE_CAT)").append(LIKE_ESCAPE) //$NON-NLS-1$
+    	.append(" AND UCASE(FKTABLE_SCHEM)").append(LIKE_ESCAPE) //$NON-NLS-1$    
+        .append(" AND UCASE(FKTABLE_NAME)").append(LIKE_ESCAPE).append("ORDER BY PKTABLE_NAME, KEY_SEQ").toString(); //$NON-NLS-1$//$NON-NLS-2$
+    
+    private final static String QUERY_COLUMNS = new StringBuffer("SELECT VDBName AS TABLE_CAT") //$NON-NLS-1$
+        .append(", SchemaName AS TABLE_SCHEM, TableName AS TABLE_NAME, Name AS COLUMN_NAME") //$NON-NLS-1$
+        .append(", convert(decodeString(DataType, '").append(TYPE_MAPPING).append("', ','), short) AS DATA_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(", DataType AS TYPE_NAME") //$NON-NLS-1$
+        .append(", CASE WHEN (DataType IN (").append(DATATYPES_WITH_NO_PRECISION) //$NON-NLS-1$
+        .append(")) THEN CASE WHEN ElementLength <= 0 THEN convert(decodeString(DataType,'").append(PRECISION_MAPPING) //$NON-NLS-1$
+        .append("',','), integer) ELSE ElementLength END ELSE CASE WHEN Precision <= 0 THEN convert(decodeString(DataType,'") //$NON-NLS-1$
+        .append(PRECISION_MAPPING).append("',','), integer) ELSE Precision END END AS COLUMN_SIZE") //$NON-NLS-1$
+        .append(", NULL AS BUFFER_LENGTH, Scale AS DECIMAL_DIGITS, Radix AS NUM_PREC_RADIX") //$NON-NLS-1$
+        .append(", convert(decodeString(NullType, '").append(NULLABILITY_MAPPING).append("', ','), integer) AS NULLABLE") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(", Description AS REMARKS, DefaultValue AS COLUMN_DEF, NULL AS SQL_DATA_TYPE, NULL AS SQL_DATETIME_SUB") //$NON-NLS-1$
+        .append(", CharOctetLength AS CHAR_OCTET_LENGTH, Position AS ORDINAL_POSITION") //$NON-NLS-1$
+        .append(", decodeString(NullType, 'No Nulls, YES, Nullable, NO, Unknown, '' ''', ',') AS IS_NULLABLE") //$NON-NLS-1$
+    	.append(", NULL AS SCOPE_CATALOG, NULL AS SCOPE_SCHEMA, NULL AS SCOPE_TABLE, NULL AS SOURCE_DATA_TYPE, CASE WHEN e.IsAutoIncremented = 'true' THEN 'YES' ELSE 'NO' END AS IS_AUTOINCREMENT") //$NON-NLS-1$
+        .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME) //$NON-NLS-1$
+        .append(".Columns e") //$NON-NLS-1$
+        .append(" WHERE UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append("AND UCASE(TableName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append("AND UCASE(Name)").append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append("AND UCASE(VDBName)").append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append(" ORDER BY TABLE_NAME, ORDINAL_POSITION").toString(); //$NON-NLS-1$
+
+    private static final String QUERY_INDEX_INFO =
+      new StringBuffer("SELECT VDBName AS TABLE_CAT, SchemaName AS TABLE_SCHEM, TableName AS TABLE_NAME") //$NON-NLS-1$
+        .append(", case when KeyType = 'Index' then TRUE else FALSE end AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, KeyName AS INDEX_NAME") //$NON-NLS-1$
+        .append(", 0 AS TYPE, convert(Position, short) AS ORDINAL_POSITION, k.Name AS COLUMN_NAME") //$NON-NLS-1$
+        .append(", NULL AS ASC_OR_DESC, 0 AS CARDINALITY, 1 AS PAGES, NULL AS FILTER_CONDITION") //$NON-NLS-1$
+        .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".KeyColumns k") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(TableName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append(" AND KeyType IN ('Index', ?)") //$NON-NLS-1$
+        .append(" ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION").toString(); //$NON-NLS-1$
+    
+    private static final String QUERY_PRIMARY_KEYS =
+      new StringBuffer("SELECT VDBName as TABLE_CAT, SchemaName AS TABLE_SCHEM, TableName AS TABLE_NAME") //$NON-NLS-1$
+        .append(", k.Name AS COLUMN_NAME, convert(Position, short) AS KEY_SEQ, KeyName AS PK_NAME") //$NON-NLS-1$
+        .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".KeyColumns k") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(TableName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append(" AND KeyType LIKE 'Primary'") //$NON-NLS-1$
+        .append(" ORDER BY COLUMN_NAME, KEY_SEQ").toString(); //$NON-NLS-1$
+    
+    private final static String QUERY_PROCEDURES =
+      new StringBuffer("SELECT VDBName AS PROCEDURE_CAT, SchemaName AS PROCEDURE_SCHEM") //$NON-NLS-1$
+        .append(", p.Name AS PROCEDURE_NAME, convert(null, string) AS RESERVED_1") //$NON-NLS-1$
+        .append(", convert(null, string) AS RESERVED_2, convert(null, string) AS RESERVED_3, p.Description AS REMARKS") //$NON-NLS-1$
+        .append(", convert(decodeString(p.ReturnsResults, 'true, ").append(DatabaseMetaData.procedureReturnsResult) //$NON-NLS-1$
+        .append(", false, ").append(DatabaseMetaData.procedureNoResult).append("'), short) AS PROCEDURE_TYPE, p.Name AS SPECIFIC_NAME FROM ") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".Procedures as p") //$NON-NLS-1$
+        .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(p.Name)").append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append(" ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME").toString(); //$NON-NLS-1$
+
+    private final static String QUERY_PROCEDURE_COLUMNS =
+      new StringBuffer("SELECT VDBName PROCEDURE_CAT, SchemaName AS PROCEDURE_SCHEM") //$NON-NLS-1$
+        .append(", ProcedureName AS PROCEDURE_NAME, p.Name AS COLUMN_NAME") //$NON-NLS-1$
+        .append(", convert(decodeString(TYPE, '").append(PARAM_DIRECTION_MAPPING).append("', ','), short) AS COLUMN_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(", convert(decodeString(DataType, '").append(TYPE_MAPPING).append("', ','), integer) AS DATA_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(", DataType AS TYPE_NAME, CASE WHEN Precision <= 0 THEN convert(decodeString(DataType,'").append(PRECISION_MAPPING) //$NON-NLS-1$
+        .append("',','), integer) ELSE Precision END AS PRECISION, CASE WHEN TypeLength <= 0 THEN convert(decodeString(DataType,'") //$NON-NLS-1$
+        .append(PRECISION_MAPPING).append("',','), integer) ELSE TypeLength END AS LENGTH, convert(Scale, short) AS SCALE") //$NON-NLS-1$
+        .append(", Radix AS RADIX, convert(decodeString(NullType, '") //$NON-NLS-1$
+        .append(PROC_COLUMN_NULLABILITY_MAPPING).append("', ','), integer) AS NULLABLE") //$NON-NLS-1$
+        .append(", convert(null, string) AS REMARKS, NULL AS COLUMN_DEF") //$NON-NLS-1$
+        .append(", NULL AS SQL_DATA_TYPE, NULL AS SQL_DATETIME_SUB, NULL AS CHAR_OCTET_LENGTH, p.Position AS ORDINAL_POSITION") //$NON-NLS-1$
+        .append(", CASE NullType WHEN 'Nullable' THEN 'YES' WHEN 'No Nulls' THEN 'NO' ELSE '' END AS IS_NULLABLE, p.ProcedureName as SPECIFIC_NAME FROM ") //$NON-NLS-1$
+        .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME)
+        .append(".ProcedureParams as p") //$NON-NLS-1$
+        .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(ProcedureName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append(" AND UCASE(p.Name) LIKE ?") //$NON-NLS-1$
+        .append(" ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, COLUMN_TYPE, POSITION").toString(); //$NON-NLS-1$
+
+    private static final String QUERY_SCHEMAS =
+      new StringBuffer("SELECT Name AS TABLE_SCHEM, VDBName AS TABLE_CATALOG") //$NON-NLS-1$
+        .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".Schemas") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(Name)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" ORDER BY TABLE_SCHEM").toString(); //$NON-NLS-1$
+    
+    private final static String TABLE_TYPE = "CASE WHEN IsSystem = 'true' and UCASE(Type) = 'TABLE' THEN 'SYSTEM TABLE' ELSE UCASE(Type) END"; //$NON-NLS-1$
+    
+    private final static String QUERY_TABLES =
+      new StringBuffer("SELECT VDBName AS TABLE_CAT, SchemaName AS TABLE_SCHEM, Name AS TABLE_NAME") //$NON-NLS-1$
+        .append(", ").append(TABLE_TYPE).append(" AS TABLE_TYPE, Description AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(", NULL AS TYPE_NAME, NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION, IsPhysical AS ISPHYSICAL") //$NON-NLS-1$
+        .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".Tables g ")  //$NON-NLS-1$ //$NON-NLS-2$
+        .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+        .append(" AND UCASE(Name)") .append(LIKE_ESCAPE).toString(); //$NON-NLS-1$
+    
+//    private static final String QUERY_UDT =
+//      new StringBuffer("SELECT NULL AS TYPE_CAT, v.Name AS TYPE_SCHEM, TypeName AS TYPE_NAME") //$NON-NLS-1$
+//        .append(", JavaClass AS CLASS_NAME, decodeString(JavaClass, '").append(UDT_NAME_MAPPING).append("', ',') AS DATA_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+//        .append(", Description AS REMARKS") //$NON-NLS-1$
+//        .append(", decodeString(BaseType, '").append(UDT_NAME_MAPPING).append("', ',') AS BASE_TYPE ") //$NON-NLS-1$ //$NON-NLS-2$
+//        .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".DataTypes CROSS JOIN ") //$NON-NLS-1$ //$NON-NLS-2$
+//        .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".VirtualDatabases v")  //$NON-NLS-1$
+//        .append(" WHERE UCASE(v.Name)").append(LIKE_ESCAPE).append("AND UCASE(TypeName)").append(LIKE_ESCAPE).append("ORDER BY DATA_TYPE, TYPE_SCHEM, TYPE_NAME ").toString(); //$NON-NLS-1$
+    
+    /** ATTRIBUTES */
+
+    // driver's connection object used in constructin this object.
+    private ConnectionImpl driverConnection;
+
+    /**
+     * <p>Constructor which initializes with the connection object on which metadata
+     * is sought
+     * @param driver's connection object.
+     * @throws SQLException if the connection is already closed.
+     */
+    DatabaseMetaDataImpl(ConnectionImpl connection) {
+        this.driverConnection = connection;
+    }
+
+    /**
+     * <p>Checks whether the current user has the required security rights to call
+     * all the procedures returned by the method getProcedures.</p>
+     * @return true if the precedures are selectable else return false
+     * @throws SQLException. Should never occur.
+     */
+    public boolean allProceduresAreCallable() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether the current user can use SELECT statement with all of the
+     * tables returned by the method getTables. Selectability is column level in
+     * metamatrix, hence return true</p>
+     * @return true if tables are selectable else return false
+     * @throws SQLException. Should never occur.
+     */
+    public boolean allTablesAreSelectable() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether a DDL statement within a transaction forces the transaction
+     * to commit.</p>
+     * @return if so return true else return false.
+     * @throws SQLException Should never occur.
+     */
+    public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether a DDL statement within a transaction is ignored.</p>
+     * @return if so return true, else false
+     * @throw SQLException Should never occur.
+     */
+    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether or not a visible row delete can be detected by
+     * calling ResultSet.rowDeleted().  If deletesAreDetected()
+     * returns false, then deleted rows are removed from the result set.
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return true if changes are detected by the resultset type
+     * @throws SQLException, should never occur
+     */
+    public boolean deletesAreDetected(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
+     * blobs?</p>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Gets a description of a table's optimal set of columns that uniquely identifies a row.</p>
+     * @param name of the catalog from which metadata needs
+     * @param catalog name in which the table is present.
+     * @param schema name in which this table is present.
+     * @param table name whose best row identifier info is sought.
+     * @param int indicating the scope of the result.
+     * @param boolean indicating whether the nullable columns can be included.
+     * @return ResultSet object containing the bestrow indetifier info.
+     */
+    public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException {
+
+        // here it always returns a empty result set, when this functionality 
+        // is being changed make sure that we check the catelog & schema here
+        // to filter.
+        
+        // list containing records/rows in the ResultSet
+        List records = new ArrayList (0);
+
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+        Map[] metadataList = new Map[8];
+
+        // HardCoding metadata details for SCOPE column
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.SCOPE,
+                            MMJDBCSQLTypeInfo.SHORT,  ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for COLUMN_NAME column
+        metadataList[1] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.COLUMN_NAME,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for DATA_TYPE column
+        metadataList[2] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.DATA_TYPE,
+                            MMJDBCSQLTypeInfo.SHORT, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for TYPE_NAME column
+        metadataList[3] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.TYPE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for COLUMN_SIZE column
+        metadataList[4] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.COLUMN_SIZE,
+                            MMJDBCSQLTypeInfo.INTEGER, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for BUFFER_LENGTH column
+        metadataList[5] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.BUFFER_LENGTH,
+                            MMJDBCSQLTypeInfo.INTEGER, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // HardCoding metadata details for DECIMAL_DIGITS column
+        metadataList[6] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.DECIMAL_DIGITS,
+                            MMJDBCSQLTypeInfo.SHORT, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for PSEUDO_COLUMN column
+        metadataList[7] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.PSEUDO_COLUMN,
+                            MMJDBCSQLTypeInfo.SHORT, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // logging
+        String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.Best_row_sucess", table); //$NON-NLS-1$
+        logger.fine(logMsg);
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, metadataList);
+    }
+
+    /**
+     * <p>Gets the catalog names available to metamatrix. The results are ordered by
+     * catalog name. There is no concept of catalogs in a metamatrix driver and this
+     * returns an empty resultSet.
+     * @return ResultSet object containing metadata info of the catalog on this connection.
+     * @throws SQLException if there is an error obtaining server results
+     */
+    public ResultSet getCatalogs() throws SQLException {
+        // list containing records/rows in the ResultSet
+        List records = new ArrayList (0);
+
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+        Map[] metadataList = new Map[1];
+
+        // HardCoding metadata details for TABLE_CAT column
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.CATALOGS.TABLE_CAT, 
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // logging
+        String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.Catalog_success"); //$NON-NLS-1$
+        logger.fine(logMsg);
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, metadataList);
+    }
+
+    private ResultSet createResultSet(List records, Map[] columnMetadata) throws SQLException {
+        ResultSetMetaData rsmd = new ResultSetMetaDataImpl(new MetadataProvider(columnMetadata));
+
+        return createResultSet(records, rsmd);
+    }
+
+    private ResultSet createResultSet(List records, ResultSetMetaData rsmd) throws SQLException {
+        ResultsMessage resultsMsg = createDummyResultsMessage(null, null, records);
+        StatementImpl stmt = StatementImpl.newInstance(this.driverConnection, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+        return new ResultSetImpl(resultsMsg, stmt, rsmd, 0);
+    }
+
+    private ResultSet createEmptyResultSet(String[] columnNames, String[] dataTypes) throws SQLException {
+        ResultsMessage resultsMsg = createDummyResultsMessage(columnNames, dataTypes, Collections.EMPTY_LIST);
+        StatementImpl stmt = StatementImpl.newInstance(this.driverConnection, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+        try {
+            stmt.setFetchSize(500);
+        } catch(SQLException e) {
+            // will never happen but throw a runtime if it does
+            throw new MetaMatrixRuntimeException(e);
+        }
+        Map[] metadata = new Map[columnNames.length];
+        for (int i = 0; i < columnNames.length; i++) {
+            metadata[i] = getColumnMetadata(null, columnNames[i], dataTypes[i], ResultsMetadataConstants.NULL_TYPES.UNKNOWN);
+        }
+        return new ResultSetImpl(resultsMsg, stmt, new ResultSetMetaDataImpl(new MetadataProvider(metadata)), 0);
+    }
+
+    private ResultsMessage createDummyResultsMessage(String[] columnNames, String[] dataTypes, List records) {
+        ResultsMessage resultsMsg = new ResultsMessage();
+        resultsMsg.setColumnNames(columnNames);
+        resultsMsg.setDataTypes(dataTypes);
+        resultsMsg.setFirstRow(1);
+        resultsMsg.setLastRow(records.size());
+        resultsMsg.setFinalRow(records.size());
+        resultsMsg.setResults((List[])records.toArray(new List[records.size()]));
+        return resultsMsg;
+    }
+
+    /**
+     * <p>Gets the String object used to separate a catalog name and a table name
+     * @return String delimiter
+     * @throws SQLException, should never occur.
+     */
+    public String getCatalogSeparator() throws SQLException {
+        return EMPTY_STRING;
+    }
+
+    /**
+     * <p>Get the metamatrix term for catalog
+     * @return String representing catalog name
+     * @throws SQLException, should never occur.
+     */
+    public String getCatalogTerm() throws SQLException {
+        return EMPTY_STRING;
+    }
+
+    /**
+     * <p>Gets a description of the access rights for a column of the given name.
+     * Catalog, schema and table names are not used to narrow down the search,
+     * but the schema name should match the virtualdatabasename used to obtain
+     * this driver connection.</p>
+     * @param name of the catalog to which columns belong.
+     * @param name of the schema to which columns belong.
+     * @param name of the table to which columns belong.
+     * @param name pattern to be matched by column names.
+     * @return ResultSet containing column privilage information.
+     * @throws SQLException if there is an error obtaining server results
+     */
+    public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnName) throws SQLException {
+        
+        List records = new ArrayList (0);
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+        Map[] metadataList = new Map[8];
+
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_CAT,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        metadataList[1] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_SCHEM,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        metadataList[2] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[3] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.COLUMN_NAME,
+                             MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[4] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTOR,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        metadataList[5] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTEE,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[6] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.PRIVILEGE,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[7] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.IS_GRANTABLE,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+       
+        return createResultSet(records, metadataList);
+        
+    }
+
+    /**
+     * <p>Get's the metadata information about the columns whose names match the given
+     * columnNamePattern. Catalog, schema and tableNamePattern are not used to
+     * narrow down the search, but Catalog and schema names should match the
+     * virtualdatabasename and version used to obtain this driver connection.</p>
+     * <p> The ResultSet returned by this method contains the following additional
+     * columns that are not specified in the JDBC specification.</p>
+     * <OL>
+     *   <LI><B>Format</B> String => format of the column
+     *   <LI><B>MinRange</B> String => minimum range value of the column
+     *   <LI><B>MaxRange</B> String => maximum range value of the column
+     * <OL>
+     * @param catalog name to which the columns belong.
+     * @param schema name to which the columns belong.
+     * @param pattern name to be matched by table name.
+     * @param pattern name to be matched by column name.
+     * @return ResultSet containing column metadata info.
+     * @throws SQLException if there is an error obtaining server results.
+     */
+    public ResultSet getColumns(String catalog, String schema, String tableNamePattern, String columnNamePattern) throws SQLException {
+
+        if (catalog == null) {
+        	catalog = PERCENT;
+        }
+        
+        if (schema == null) {
+            schema = PERCENT;
+        }
+        // Get columns in all the tables if tableNamePattern is null
+        if(tableNamePattern == null) {
+            tableNamePattern = PERCENT; 
+        }
+        // Get all columns if columnNamePattern is null
+        if(columnNamePattern == null) {
+            columnNamePattern = PERCENT; 
+        }
+
+        // list which represent records containing column info
+        List records = new ArrayList ();
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+
+        try {
+            prepareQuery = driverConnection.prepareStatement(QUERY_COLUMNS); 
+            prepareQuery.setObject(1, schema.toUpperCase());
+            prepareQuery.setObject(2, tableNamePattern.toUpperCase());
+            prepareQuery.setObject(3, columnNamePattern.toUpperCase());
+            prepareQuery.setObject(4, catalog.toUpperCase());
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+
+            // build the list of records of column description
+            while (results.next ()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList(JDBCColumnPositions.COLUMNS.MAX_COLUMNS);
+
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                for(int i=0; i < JDBCColumnPositions.COLUMNS.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+                records.add(currentRow);
+            }// end of while
+
+            // get the metadata for the results
+            rmetadata = results.getMetaData();
+
+        } catch(Exception e) {
+            // logging
+            String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.getCols_error", columnNamePattern, tableNamePattern, e.getMessage()); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, logMsg);
+        }
+
+        // logging
+        String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.getCols_success", columnNamePattern, tableNamePattern); //$NON-NLS-1$
+        logger.fine(logMsg);
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>Gets the description of the foreign key columns in the table foreignTable.
+     * These foreign key columns reference primary key columns of primaryTable.
+     * Catalog and schema information is not used to narrow down the search, but
+     * Catalog and schema names(primary and foreign) should match the
+     * virtualdatabasename and version used to obtain this driver connection.
+     * @param name of the catalog containing primary keys.
+     * @param name of the schema containing primary keys.
+     * @param name of the table containing primary keys.
+     * @param name of the catalog containing foreign keys.
+     * @param name of the schema containing foreign keys.
+     * @param name of the table containing foreign keys.
+     * @return ResultSet giving description of foreign key columns.
+     * @throws SQLException if there is an error obtaining server results
+     */
+    public ResultSet getCrossReference(String primaryCatalog, String primarySchema,String primaryTable,String foreignCatalog,String foreignSchema, String foreignTable) throws SQLException {
+        
+    	if (primaryCatalog == null) {
+            primaryCatalog = PERCENT;
+        }
+    	
+    	if (foreignCatalog == null) {
+            foreignCatalog = PERCENT;
+        }
+        
+        if (primarySchema == null) {
+            primarySchema = PERCENT;
+        }
+        
+        if (foreignSchema == null) {
+            foreignSchema = PERCENT;
+        }
+        
+        if (primaryTable == null) {
+            primaryTable = PERCENT; 
+        }
+
+        if (foreignTable == null) {
+            foreignTable = PERCENT; 
+        }
+
+        ResultSetImpl results = null;
+        try {
+            PreparedStatement prepareQuery = driverConnection.prepareStatement(QUERY_CROSS_REFERENCES);
+            prepareQuery.setObject(1, primaryCatalog.toUpperCase());
+            prepareQuery.setObject(2, foreignCatalog.toUpperCase());
+            prepareQuery.setObject(3, primarySchema.toUpperCase());
+            prepareQuery.setObject(4, foreignSchema.toUpperCase());
+            prepareQuery.setObject(5, primaryTable.toUpperCase());
+            prepareQuery.setObject(6, foreignTable.toUpperCase());
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+        } catch(Exception e) {
+            // logging
+            String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.getCrossRef_error", primaryTable, foreignTable, e.getMessage()); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, logMsg);
+        }
+
+        ResultSet resultSet = getReferenceKeys(results);
+
+        // logging
+        String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.getCrossRef_success", primaryTable, foreignTable); //$NON-NLS-1$
+        logger.fine(logMsg);
+
+        return resultSet;
+    }
+
+    /**
+     * Retrieves the minor version number of the underlying database.
+     * @return intValue of database's minor version
+     * @throws SQLException if a database access error occurs.
+     */
+    public int getDatabaseMinorVersion() throws SQLException {
+        return TeiidDriver.getInstance().getMinorVersion();
+    }
+
+    /**
+     * Retrieves the major version number of the underlying database.
+     * @return intValue of database's minor version
+     * @throws SQLException if a database access error occurs.
+     */
+    public int getDatabaseMajorVersion() throws SQLException {
+        return TeiidDriver.getInstance().getMajorVersion();
+    }
+
+    /**
+     * Retrieves the major JDBC version number for this driver.
+     * @return intValue JDBC major version number
+     * @throws SQLException should never occur.
+     */
+    public int getJDBCMajorVersion()  throws SQLException {
+        return 3;
+    }
+
+    /**
+     * Retrieves the minor JDBC version number for this driver.
+     * @return intValue JDBC major version number
+     * @throws SQLException should never occur.
+     */
+    public int getJDBCMinorVersion()  throws SQLException {
+        return 0;
+    }
+
+    /**
+     * <p>Gets the product name for this database
+     * @return String representing the product name
+     * @throws SQLException should never occur.
+     */
+    public String getDatabaseProductName() throws SQLException {
+        return this.driverConnection.getDatabaseName();
+    }
+
+    /**
+     * <p>Gets the version of metamatrix server to which this driver connects
+     * @return String representing the product version
+     * @throws SQLException if there is an error accessing product release info.
+     */
+    public String getDatabaseProductVersion() throws SQLException {
+        return TeiidDriver.getInstance().getMajorVersion() + "." + TeiidDriver.getInstance().getMinorVersion(); //$NON-NLS-1$
+    }
+
+    /**
+     * <p>Gets metamatrix default transaction isolation level.
+     * @return intvalue giving the transaction isolation level
+     * @throws SQLException never
+     */
+    public int getDefaultTransactionIsolation() throws SQLException {
+        return Connection.TRANSACTION_NONE;
+    }
+
+    /**
+     * <p>Gets this drivers major version number
+     * @return int representing the driver's major version
+     */
+    public int getDriverMajorVersion() {
+        return TeiidDriver.getInstance().getMajorVersion();
+    }
+
+    /**
+     * <p>Gets this drivers minor version number
+     * @return int representing the driver's minor version
+     */
+    public int getDriverMinorVersion() {
+        return TeiidDriver.getInstance().getMinorVersion();
+    }
+
+    /**
+     * <p>Get the name of this JDBC driver
+     * @return String representing the driver's name
+     * @throws SQLException, if the connection is already closed.
+     */
+    public String getDriverName() throws SQLException {
+        return TeiidDriver.getInstance().getDriverName();
+    }
+
+    /**
+     * <p>This method gets the version of this JDBC driver. It combines the major
+     * and minor version numbers
+     * @return String representing the driver's version
+     * @throws SQLException, should never occur.
+     */
+    public String getDriverVersion() throws SQLException {
+        return getDriverMajorVersion()+"."+getDriverMinorVersion (); //$NON-NLS-1$
+    }
+
+    /**
+     * <p>This method gets a description of the forignkey columns that reference the
+     * primary key columns in the given table.  Catalog and schema names are not
+     * used to narrow down the search, but they should match the virtualdatabasename
+     * and version used to obtain this driver connection.
+     * @param name of the catalog which contains the given table.
+     * @param schema name which contains the given table.
+     * @param table name which contains the primary keys.
+     * @return ResultSet object giving the exported key info.
+     * @throws SQLException if there is an error obtaining server results
+     */
+    public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
+        if (catalog == null) {
+        	catalog = PERCENT;
+        }
+        
+        if (schema == null) {
+            schema = PERCENT;
+        }
+        
+        if (table == null) {
+            table = PERCENT; 
+        }
+
+        ResultSetImpl results = null;
+        try {
+            PreparedStatement prepareQuery = driverConnection.prepareStatement(QUERY_EXPORTED_KEYS);
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schema.toUpperCase());
+            prepareQuery.setObject(3, table.toUpperCase());
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+        } catch(Exception e) {
+            // logging
+            String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.getExpKey_error", table, e.getMessage()); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, logMsg);
+        }
+
+        ResultSet resultSet = getReferenceKeys(results);
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getExpKey_success", table));//$NON-NLS-1$
+
+        return resultSet;
+    }
+
+    /**
+     * <p>Gets the extra characters that can be used in unquoted identifier names
+     * (those beyond a-z, 0-9, and _)
+     * @return String representing extra charachters that can be used in identifier names.
+     * @throws SQLException, should never occur
+     */
+    public String getExtraNameCharacters() throws SQLException {
+        return EXTRA_CHARS;// ".@" is use in fully qualified identifier names
+    }
+
+    /**
+     * <p>Get's the string used to quote SQL identifiers. This returns a " " if identifier
+     * quoting is not supported.
+     * @return string used to quote SQL identifiers.
+     * @throws SQLException, should never occur
+     */
+    public String getIdentifierQuoteString() throws SQLException {
+        return DOUBLE_QUOTE;
+    }
+
+    /**
+     * <p>Gets a description of the primary key columns that are referenced by the
+     * foreign key columns in the given table. Catalog and schema names are not
+     * used to narrow down the search, but they should match the virtualdatabasename
+     * and version used to obtain this driver connection.
+     * @param name of the catalog which contains the given table.
+     * @param schema name which contains the given table.
+     * @param table name which contains the foreign keys.
+     * @return ResultSet object giving the imported key info.
+     * @throws SQLException if there is an error obtaining server results
+     */
+    public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
+    	if (catalog == null) {
+        	catalog = PERCENT;
+        }
+        
+        if (schema == null) {
+            schema = PERCENT;
+        }
+        
+        if (table == null) {
+            table = PERCENT; 
+        }
+
+        ResultSetImpl results = null;
+        try {
+            PreparedStatement prepareQuery = driverConnection.prepareStatement(QUERY_IMPORTED_KEYS);
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schema.toUpperCase());
+            prepareQuery.setObject(3, table.toUpperCase());
+
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+        } catch(Exception e) {
+            String logMsg = JDBCPlugin.Util.getString("MMDatabaseMetadata.getImpKey_error", table, e.getMessage()); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, logMsg);
+        }
+
+        ResultSet resultSet = getReferenceKeys(results);
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getImpKey_success", table)); //$NON-NLS-1$
+
+        return resultSet;
+    }
+
+    /**
+     * <p>Gets a description of the indexes that are present on a given table.
+     *
+     * @param name of the catalog which contains the given table.
+     * @param schema name which contains the given table.
+     * @param table name which contains the indexes.
+     * @param boolean indicating if unique key info needs to be returned.
+     * @param boolean indicating if approximate value are to be allowed.
+     * @return ResultSet object containing metadata info of index columns.
+     * @throws SQLException if catalog/schema info does not match for this connection.
+     */
+    public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
+        if (catalog == null) {
+        	catalog = PERCENT;
+        }
+        
+        if (schema == null) {
+            schema = PERCENT;
+        }
+        
+        if (table == null) {
+            table = PERCENT; 
+        }
+        // list which represent records containing primary key info
+        List records = new ArrayList ();
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+
+        try {
+            prepareQuery = driverConnection.prepareStatement(QUERY_INDEX_INFO); 
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schema.toUpperCase());
+            prepareQuery.setObject(3, table.toUpperCase());
+            prepareQuery.setObject(4, unique?null:"NonUnique"); //$NON-NLS-1$
+            
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+
+            // build the list of records from server's Results object.
+            while (results.next ()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList (13);
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                for(int i=0; i < JDBCColumnPositions.INDEX_INFO.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                // add the current row to the list of records.
+                records.add(currentRow);
+            }// end of while
+
+            // get the metadata for the results
+            rmetadata = results.getMetaData();
+
+        } catch (Exception e) {
+            throw TeiidSQLException.create(e, JDBCPlugin.Util.getString("MMDatabaseMetadata.getIndex_error", table, e.getMessage())); //$NON-NLS-1$
+        }
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getIndex_success", table)); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>Gets the maximum number of hexadecimal characters allowed in an inline
+     * binary literal
+     * @return int value giving maximum length of a binary literal
+     * @throws SQLException, should never occur
+     */
+    public int getMaxBinaryLiteralLength() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a catalog name
+     * @return int value giving maximum length of a catalog name
+     * @throws SQLException, should never occur
+     */
+    public int getMaxCatalogNameLength() throws SQLException {
+        return MAX_CATALOG_NAME_LENGTH;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a character literal
+     * @return int value giving maximum length of a charachter literal
+     * @throws SQLException, should never occur
+     */
+    public int getMaxCharLiteralLength() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a column name
+     * @return int value giving maximum length of the column name
+     * @throws SQLException, should never occur
+     */
+    public int getMaxColumnNameLength() throws SQLException {
+        return MAX_COLUMN_NAME_LENGTH;
+    }
+
+    /**
+     * <p>Gets the maximum number of columns allowed in a GROUP BY clause
+     * @return int values giving max columns in GROUP BY
+     * @throws SQLException, should never occur
+     */
+    public int getMaxColumnsInGroupBy() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of columns allowed in an index
+     * @return int gives maximum columns in an index.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxColumnsInIndex() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of columns allowed in a ORDER BY clause
+     * @return int gives maximum columns in an order by.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxColumnsInOrderBy() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of columns allowed in a SELECT clause
+     * @return int gives maximum columns in a select.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxColumnsInSelect() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of columns allowed in a table
+     * @return int gives maximum columns in a table.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxColumnsInTable() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of active connections to metamatrix that can be
+     * maintained through this driver instance
+     * @return int gives maximum connections.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxConnections() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a cursor name
+     * @return int gives maximum max charachters allowed in a cursor name.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxCursorNameLength() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of bytes allowed in an index
+     * @return int gives maximum bytes.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxIndexLength() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a procedure name
+     * @return int gives maximum length of procedure name.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxProcedureNameLength() throws SQLException {
+        return MAX_PROCEDURE_NAME_LENGTH;
+    }
+
+    /**
+     * <p>Gets the maximum number of bytes allowed in a single row
+     * @return int max row size in the result set.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxRowSize() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a schema name
+     * @return int maximum length of a schema.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxSchemaNameLength() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in an SQL statement
+     * @return maximum length of a statement
+     * @throws SQLException, should never occur
+     */
+    public int getMaxStatementLength() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of active statements that may be open on one
+     * connection at any time
+     * @return max number of open statements on a connection.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxStatements() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a table name
+     * @return max length of table name.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxTableNameLength() throws SQLException {
+        return MAX_TABLE_NAME_LENGTH;
+    }
+
+    /**
+     * <p>Gets the maximum number of tables allowed in a SELECT clause
+     * @return max tables in a select.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxTablesInSelect() throws SQLException {
+        return NO_LIMIT;
+    }
+
+    /**
+     * <p>Gets the maximum number of characters allowed in a user name
+     * @return max length of user name.
+     * @throws SQLException, should never occur
+     */
+    public int getMaxUserNameLength() throws SQLException {
+        return MAX_USER_NAME_LENGTH;
+    }
+
+    /**
+     * <p>Gets the OPEN GROUP CLI names of metamatrix math functions
+     * @return string giving numeric functions supported.
+     * @throws SQLException, should never occur
+     */
+    public String getNumericFunctions() throws SQLException {
+        return NUMERIC_FUNCTIONS;
+    }
+
+    /**
+     * <p>Get's a description of the primary key columns in a table. The descriptions
+     * are ordered by column name. Catalog and schema names are not used to narrow
+     * down the search, but they should match the virtualdatabasename and version
+     * used to obtain this driver connection.
+     * @param name of the catalog which contains the given table.
+     * @param schema name which contains the given table.
+     * @param table name which contains the primary keys.
+     * @return ResultSet object containing primary keys of the given table.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
+        if (catalog == null) {
+            catalog = PERCENT;
+        }
+        
+        if (schema == null) {
+            schema = PERCENT;
+        }
+        
+        if (table == null) {
+            table = PERCENT; 
+        }
+
+        // list which represent records containing primary key info
+        List records = new ArrayList ();
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+        try {
+            prepareQuery = driverConnection.prepareStatement(QUERY_PRIMARY_KEYS);
+
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schema.toUpperCase());
+            prepareQuery.setObject(3, table.toUpperCase());
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+
+            // build the list of records from server's Results object.
+            while (results.next ()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList (7);
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                for(int i=0; i < JDBCColumnPositions.PRIMARY_KEYS.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                // add the current row to the list of records.
+                records.add(currentRow);
+            }// end of while
+
+            // get the metadata for the results
+            rmetadata = results.getMetaData();
+
+        } catch (Exception e) {
+            throw TeiidSQLException.create(e, JDBCPlugin.Util.getString("MMDatabaseMetadata.getPrimaryKey_error", table, e.getMessage())); //$NON-NLS-1$
+        }
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getPrimaryKey_success")); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>Gets a description of the input, output and results associated with certain
+     * stored procedures matching the given procedureNamePattern. Catalog and
+     * schema names are not used to narrow down the search, but they should match
+     * the virtualdatabasename and version used to obtain this driver connection.</p>
+     * @param name of the catalog the procedure is present in.
+     * @param pattern of schama name the procedure is present in.
+     * @param pattern which is to be matched by the procedureNames.
+     * @param pattern to be matched by the column names.
+     * @return ResultSet containing the metadata info for procedure parameters.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException {
+        if (catalog == null) {
+            catalog = PERCENT;
+        }
+        if (schemaPattern == null) {
+            schemaPattern = PERCENT;
+        }
+        
+        // Get all columns in all procedures if procedureNamePattern is null
+        if(procedureNamePattern == null) {
+            procedureNamePattern = PERCENT; 
+        }
+        // Get all columns if columnNamePattern is null
+        if(columnNamePattern == null) {
+            columnNamePattern = PERCENT; 
+        }
+
+        // list which represent records containing procedure column info
+        List records = new ArrayList ();
+
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+        try {
+            prepareQuery = driverConnection.prepareStatement(QUERY_PROCEDURE_COLUMNS);
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schemaPattern.toUpperCase());
+            prepareQuery.setObject(3, procedureNamePattern.toUpperCase());
+            prepareQuery.setObject(4, columnNamePattern.toUpperCase());
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+            // build the list of records from server's Results object.
+            while (results.next ()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList (13);
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                for(int i=0; i < JDBCColumnPositions.PROCEDURE_COLUMNS.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                // add the current row to the list of records.
+                records.add(currentRow);
+            }// end of while
+            rmetadata = results.getMetaData();
+
+        } catch (Exception e) {
+           throw TeiidSQLException.create(e, JDBCPlugin.Util.getString("MMDatabaseMetadata.getProcCol_error", columnNamePattern, e.getMessage())); //$NON-NLS-1$
+        }
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getProcCol_success", columnNamePattern, procedureNamePattern)); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>Gets description of all the available stored procedures whose names match
+     * the given pattern. Catalog and schemaPattern are not used to narrow down
+     * the search, but they should match the virtualdatabasename and version used
+     * to obtain this driver connection.
+     * @param name of the catalog.
+     * @param name of the schema.
+     * @param pattern which is to be matched by the procedureNames.
+     * @return ResultSet object which gives the metadata information about procedures.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException {
+	    if (catalog == null) {
+	    	catalog = PERCENT;
+	    }
+    	
+        if (schemaPattern == null) {
+            schemaPattern = PERCENT;
+        }
+        
+        // Get all procedures if procedureNamePattern is null
+        if(procedureNamePattern == null) {
+            procedureNamePattern = PERCENT; 
+        }
+
+        // list which represent records containing procedure info
+        List records = new ArrayList ();
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+
+        try {
+            prepareQuery = driverConnection.prepareStatement(QUERY_PROCEDURES);
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schemaPattern.toUpperCase());
+            prepareQuery.setObject(3, procedureNamePattern.toUpperCase());
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+
+            // build the list of records from server's Results object.
+            while (results.next ()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList (JDBCColumnPositions.PROCEDURES.MAX_COLUMNS);
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                // there are 3 columns are reserved for future use
+                for(int i=0; i < JDBCColumnPositions.PROCEDURES.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                // add the current row to the list of records.
+                records.add(currentRow);
+
+            }// end of while
+            // get the metadata for the results
+            rmetadata = results.getMetaData();
+
+        } catch (Exception e) {
+            throw TeiidSQLException.create(e, JDBCPlugin.Util.getString("MMDatabaseMetadata.getProc_error", procedureNamePattern, e.getMessage())); //$NON-NLS-1$
+        }
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getProc_success", procedureNamePattern)); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>Gets MetaMatrix's preferred term for procedures
+     * @return String representing metamatrix procedure term.
+     * @throws SQLException, should never occur
+     */
+    public String getProcedureTerm() throws SQLException {
+        return PROCEDURE_TERM;
+    }
+
+    /**
+     * <p>Gets the schema names available for this connection. The results are ordered
+     * by schema name. Schema information retreived only for the schema to which
+     * used in obtaining this driver connection.
+     * @return ResultsSet object containing schema and catalog names.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getSchemas() throws SQLException {
+    	return getSchemas(null, null);
+    }
+
+    /**
+     * <p>Gets MetaMatrix's preferred term for schema
+     * @return String object giving schema term
+     * @throws SQLException, should never occur
+     */
+    public String getSchemaTerm() throws SQLException {
+        return SCHEMA_TERM;
+    }
+
+    /**
+     * <p>Gets the string that can be used to escape "_" or "%" wildcards in the
+     * string search pattern used for search parameters
+     * @return String that is used for escaping wildcards
+     * @throws SQLException, should never occur
+     */
+    public String getSearchStringEscape() throws SQLException {
+        return ESCAPE_SEARCH_STRING;
+    }
+
+    /**
+     * <p>Get metamatrix keywords that are not SQL-92 keyword
+     * @return String object giving non SQL-92 keywords
+     * @throws SQLException, should never occur
+     */
+    public String getSQLKeywords() throws SQLException {
+        return KEY_WORDS;
+    }
+
+    /**
+     * Indicates whether the SQLSTATE returned by SQLException.getSQLState is X/Open
+     * (now known as Open Group) SQL CLI or SQL99.
+     * @return intValue, the type of SQLSTATE; one of: sqlStateXOpen or sqlStateSQL99
+     */
+    public int getSQLStateType() throws SQLException {
+        //return sqlStateSQL99;
+        return 2;
+    }
+
+    /**
+     * <p>Gets the Open Group CLI names for metamatrix string functions
+     * @return String containing string function names
+     * @throws SQLException, should never occur
+     */
+    public String getStringFunctions() throws SQLException {
+        return STRING_FUNCTIONS;
+    }
+
+    /**
+     * Retrieves a description of the table hierarchies defined in a
+     * particular schema in this database.
+     * @param catalog A catalog name; "" retrieves those without a catalog;
+     * null means drop catalog name from the selection criteria.
+     * @param schemaPattern A schema name pattern; "" retrieves those without a schema.
+     * @param tableNamePattern A table name pattern; may be a fully-qualified name.
+     * @throws SQLException since not supported
+     */
+    public ResultSet getSuperTables(String catalog, String schemaPattern,
+        String tableNamePattern) throws SQLException {
+        List records = new ArrayList (0);
+
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+        Map[] metadataList = new Map[4];
+
+        // HardCoding metadata details for TABLE_CAT column
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.SUPER_TABLES.TABLE_CAT,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // HardCoding metadata details for TABLE_SCHEM column
+        metadataList[1] = getColumnMetadata(null, JDBCColumnNames.SUPER_TABLES.TABLE_SCHEM,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // HardCoding metadata details for TABLE_NAME column
+        metadataList[2] = getColumnMetadata(null, JDBCColumnNames.SUPER_TABLES.TABLE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for SUPERTABLE_NAME column
+        metadataList[3] = getColumnMetadata(null, JDBCColumnNames.SUPER_TABLES.SUPERTABLE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, metadataList);
+
+    }
+
+    /**
+     * Retrieves a description of the user-defined type (UDT) hierarchies
+     * defined in a particular schema in this database.
+     * @param catalog A catalog name; "" retrieves those without a catalog;
+     * null means drop catalog name from the selection criteria.
+     * @param schemaPattern A schema name pattern; "" retrieves those without a schema.
+     * @param tableNamePattern A table name pattern; may be a fully-qualified name.
+     */
+    public ResultSet getSuperTypes(String catalog, String schemaPattern,
+        String tableNamePattern) throws SQLException {
+        List records = new ArrayList (0);
+
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+        Map[] metadataList = new Map[6];
+
+        // HardCoding metadata details for TYPE_CAT column
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.TYPE_CAT,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // HardCoding metadata details for TYPE_SCHEM column
+        metadataList[1] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.TYPE_SCHEM,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // HardCoding metadata details for TYPE_NAME column
+        metadataList[2] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.TYPE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        // HardCoding metadata details for SUPERTYPE_CAT column
+        metadataList[3] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.SUPERTYPE_CAT,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+        // HardCoding metadata details for SUPERTYPE_SCHEM column
+        metadataList[4] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.SUPERTYPE_SCHEM,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        
+        // HardCoding metadata details for SUPERTYPE_NAME column
+        metadataList[5] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.SUPERTYPE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        
+        // construct results object from column values and their metadata
+        return createResultSet(records, metadataList);
+    }
+
+    /**
+     * <p>Gets the Open Group CLI names for metamatrix system functions
+     * @return String containing system function names
+     * @throws SQLException, should never occur
+     */
+    public String getSystemFunctions() throws SQLException {
+        return SYSTEM_FUNCTIONS; // there are no system functions
+    }
+
+    /**
+     * <p>Gets a description of access rights for the table of the given name.
+     * <p>Catalog and schemaPattern are not used to narrow down the search, but they
+     * should match the virtualdatabasename and version used to obtain this driver
+     * connection.
+     * @param name of the catalog the table is present in.
+     * @param pattern of schama name the table is present in.
+     * @param pattern of table names whose privilage info is needed.
+     * @return ResultSet containing table privilages info.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableName) throws SQLException {
+        List records = new ArrayList (0);
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+        Map[] metadataList = new Map[7];
+
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_CAT,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        metadataList[1] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_SCHEM,
+                            MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        metadataList[2] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_NAME,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[3] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTOR,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+        metadataList[4] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTEE,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[5] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.PRIVILEGE,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+        metadataList[6] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.IS_GRANTABLE,
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+       
+        return createResultSet(records, metadataList);
+        
+    }
+
+    /**
+     * <p>Gets a description of tables whose table name matches tableNamePattern.
+     * <p>Catalog, schemaPattern and types[] are not used to narrow down the search,
+     * but catalog and schemaPattern should match the virtualdatabasename and
+     * version respectively used to obtain this driver connection.
+     * Note:
+     * supports 1.4 API
+     * @param name of the catalog in which tables are present.
+     * @param pattern of schema names which in which the tables are present.
+     * @param pattern of tables names.
+     * @param list of possible table types.
+     * @return ResultSet containing Table metadata information.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[]) throws SQLException {
+        if (catalog == null) {
+        	catalog = PERCENT;
+        }
+        
+        if (schemaPattern == null) {
+            schemaPattern = PERCENT;    
+        }
+        
+        // Get all tables if tableNamePattern is null
+        if(tableNamePattern == null) {
+            tableNamePattern = PERCENT; 
+        }
+
+        // list which represent records containing tables info
+        List records = new ArrayList ();
+
+        // query string to be submitted to get table metadata info
+        StringBuffer sqlQuery = new StringBuffer(QUERY_TABLES);
+
+        StringBuffer typesString = new StringBuffer("("); // criteria string for different table types //$NON-NLS-1$
+        
+        if (types != null) {
+            // construct the criteria string
+            for(int i=0; i < types.length; i++) {
+                if (types[i] != null && types[i].length() > 0) {
+                    if (i > 0) {
+                        typesString.append(" OR "); //$NON-NLS-1$
+                    } 
+                    typesString.append(TABLE_TYPE).append(LIKE_ESCAPE);
+                }
+            }
+            typesString.append(")"); //$NON-NLS-1$
+            sqlQuery.append(" AND ").append(typesString.toString()); //$NON-NLS-1$
+        }
+
+        sqlQuery.append(" ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME"); //$NON-NLS-1$
+
+
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+
+        try {
+            prepareQuery = driverConnection.prepareStatement(sqlQuery.toString());
+            int columnIndex = 0;
+            prepareQuery.setObject(++columnIndex, catalog.toUpperCase());
+            prepareQuery.setObject(++columnIndex, schemaPattern.toUpperCase());
+            prepareQuery.setObject(++columnIndex, tableNamePattern.toUpperCase());
+
+            if(types != null) {
+                for(int i=0; i < types.length; i++) {
+                    if (types[i] != null && types[i].length() > 0) {
+                        prepareQuery.setObject(++columnIndex, types[i].toUpperCase());
+                    }
+                }
+            }
+
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+
+            // build the list of records from server's Results object.
+            while (results.next ()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList (11);
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                for(int i=0; i < JDBCColumnPositions.TABLES.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                // add the current row to the list of records.
+                records.add(currentRow);
+            }// end of while
+
+            // get the metadata for the results
+            rmetadata = results.getMetaData();
+        } catch (SQLException e) {
+            throw e;
+        } catch (Exception e) {
+            throw TeiidSQLException.create(e, JDBCPlugin.Util.getString("MMDatabaseMetadata.getTable_error", tableNamePattern, e.getMessage())); //$NON-NLS-1$
+        }
+
+        // close the results (need to close case results exceed cursor size)
+        //results.close();
+
+        // close the PreparedStatement, too. Because of the way of closing request in current framework,
+        // manually send out a close request is very necessary for PreparedStatement.
+        //prepareQuery.close();
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getTable_success", tableNamePattern)); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>Gets the table types available to metamatrix. The results are ordered by
+     * table type
+     * @return ResultSet object containing hardcoded table type info.
+     * @throws SQLException, should never occur.
+     */
+    public ResultSet getTableTypes() throws SQLException {
+
+        // list which represent records containing Table Type info
+        List records = new ArrayList (5);
+        /********************************
+        * HardCoding JDBC specific values
+        *********************************/
+
+        records.add(Arrays.asList(new String[] {"DOCUMENT"})); //$NON-NLS-1$
+        records.add(Arrays.asList(new String[] {"TABLE"})); //$NON-NLS-1$
+        records.add(Arrays.asList(new String[] {"VIEW"})); //$NON-NLS-1$
+        records.add(Arrays.asList(new String[] {"XMLSTAGINGTABLE"})); //$NON-NLS-1$
+        records.add(Arrays.asList(new String[] {"SYSTEM TABLE"})); //$NON-NLS-1$
+
+        /***********************************************************************
+        * Hardcoding JDBC column names for the columns returned in results object
+        ***********************************************************************/
+
+        Map[] metadataList = new Map[1];
+
+        metadataList[0] = getColumnMetadata(null, JDBCColumnNames.TABLE_TYPES.TABLE_TYPE, 
+                            MMJDBCSQLTypeInfo.STRING, ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getTableType_success")); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, metadataList);
+    }
+
+    /**
+     * <p>Gets the Open Group CLI names for metamatrix time and date functions
+     * @return String representing time and date functions in MetaMatrix
+     * @throws SQLException, should never occur
+     */
+    public String getTimeDateFunctions() throws SQLException {
+        return DATE_FUNCTIONS;
+    }
+
+    /**
+     * <p>Gets the description of all datatypes supported by metamatrix.
+     * @return ResultSet object containing info about the datatypes supported by MetaMatrix.
+     * @throws SQLException if there is an error obtaining metamatrix results.
+     */
+    public ResultSet getTypeInfo() throws SQLException {
+
+        // list which represent records containing data type info
+        List records = new ArrayList ();
+
+        records.add(Arrays.asList(createTypeInfoRow("boolean",  "{b'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        records.add(Arrays.asList(createTypeInfoRow("byte", null, null, Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("long", null, null, Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("char", "'", "'", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        records.add(Arrays.asList(createTypeInfoRow("bigdecimal",null, null, Boolean.FALSE, Boolean.TRUE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("biginteger", null, null, Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("integer",  null, null, Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("short", null, null, Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("float", null, null, Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("double",  null, null, Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("string", "'", "'", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+        records.add(Arrays.asList(createTypeInfoRow("xml", null, null, Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("date", "{d'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+        records.add(Arrays.asList(createTypeInfoRow("time", "{t'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+        records.add(Arrays.asList(createTypeInfoRow("timestamp",  "{ts'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+        records.add(Arrays.asList(createTypeInfoRow("object", null, null, Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("blob", null, null, Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ 
+        records.add(Arrays.asList(createTypeInfoRow("clob", null, null, Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ 
+
+        Map[] metadataList = new Map[18];
+
+        metadataList[0] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.TYPE_NAME, MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NOT_NULL, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[1] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.DATA_TYPE, MMJDBCSQLTypeInfo.INTEGER,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[2] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.PRECISION, MMJDBCSQLTypeInfo.INTEGER,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[3] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.LITERAL_PREFIX, MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE,  ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[4] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.LITERAL_SUFFIX, MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE,  ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[5] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.CREATE_PARAMS, MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NULLABLE,  ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[6] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.NULLABLE, MMJDBCSQLTypeInfo.SHORT,  ResultsMetadataConstants.NULL_TYPES.NULLABLE,  ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[7] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.CASE_SENSITIVE, MMJDBCSQLTypeInfo.BOOLEAN,  ResultsMetadataConstants.NULL_TYPES.NOT_NULL, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE, Boolean.TRUE);//$NON-NLS-1$ 
+        metadataList[8] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.SEARCHABLE, MMJDBCSQLTypeInfo.SHORT,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[9] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.UNSIGNED_ATTRIBUTE, MMJDBCSQLTypeInfo.BOOLEAN,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[10] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.FIXED_PREC_SCALE, MMJDBCSQLTypeInfo.BOOLEAN,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$
+        metadataList[11] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.AUTOINCREMENT, MMJDBCSQLTypeInfo.BOOLEAN,  ResultsMetadataConstants.NULL_TYPES.NOT_NULL, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.TRUE, Boolean.TRUE);//$NON-NLS-1$ 
+        metadataList[12] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.LOCAL_TYPE_NAME, MMJDBCSQLTypeInfo.STRING,  ResultsMetadataConstants.NULL_TYPES.NOT_NULL, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[13] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.MINIMUM_SCALE, MMJDBCSQLTypeInfo.SHORT,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[14] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.MAXIMUM_SCALE, MMJDBCSQLTypeInfo.SHORT,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[15] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.SQL_DATA_TYPE, MMJDBCSQLTypeInfo.INTEGER,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[16] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.SQL_DATETIME_SUB, MMJDBCSQLTypeInfo.INTEGER,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);//$NON-NLS-1$ 
+        metadataList[17] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." + DATA_TYPES, JDBCColumnNames.TYPE_INFO.NUM_PREC_RADIX, MMJDBCSQLTypeInfo.INTEGER,  ResultsMetadataConstants.NULL_TYPES.NULLABLE, ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE);//$NON-NLS-1$ 
+
+        ResultSetMetaData rmetadata = new ResultSetMetaDataImpl(new MetadataProvider(metadataList));
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getTypes_success")); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    private Object[] createTypeInfoRow(String typeName, String prefix, String suffix, Boolean unsigned, Boolean fixedPrecScale, int radix){
+        return new Object[] {typeName, new Integer(MMJDBCSQLTypeInfo.getSQLType(typeName)), ResultsMetadataDefaults.getDefaultPrecision(typeName), prefix, suffix, null, new Short((short)DatabaseMetaData.typeNullable), Boolean.FALSE, new Short((short)DatabaseMetaData.typeSearchable), unsigned, fixedPrecScale, Boolean.FALSE, typeName, new Short((short)0), new Short((short)255), null, null, new Integer(radix)};
+    }
+    
+    /**
+     * <p>Gets a description of the user-defined types defined in a particular
+     * schema.  Schema-specific UDTs may have type JAVA_OBJECT, STRUCT, or DISTINCT.
+     * Supports 1.4
+     * @param catalog a catalog name
+     * @param schemaPattern a schema name pattern
+     * @param typeNamePattern a type name pattern
+     * @param types a list of user-named types to include (JAVA_OBJECT, STRUCT,
+     * or DISTINCT); null returns all types
+     * @return ResultSet. Empty ResultSet object as this method is not supported.
+     * @throws SQLException if catalog/schema info does not match for the given connection.
+     */
+    public ResultSet getUDTs(String catalog, String schemaPattern,
+        String typeNamePattern, int[] types) throws SQLException {
+        return emptyUDTSResultSet();
+    }
+    
+    /**
+     * Return a empty result set for to aid getUDTS() functions. 
+     * @return ResultSet.
+     */
+    private ResultSet emptyUDTSResultSet() throws SQLException {
+        String[] columnNames = new String[] {
+                JDBCColumnNames.UDTS.TYPE_CAT,
+                JDBCColumnNames.UDTS.TYPE_SCHEM,
+                JDBCColumnNames.UDTS.TYPE_NAME,
+                JDBCColumnNames.UDTS.CLASS_NAME,
+                JDBCColumnNames.UDTS.DATA_TYPE,
+                JDBCColumnNames.UDTS.REMARKS,
+                JDBCColumnNames.UDTS.BASE_TYPE
+        };
+        String[] dataTypes = new String[] {
+                MMJDBCSQLTypeInfo.STRING,
+                MMJDBCSQLTypeInfo.STRING,
+                MMJDBCSQLTypeInfo.STRING,
+                MMJDBCSQLTypeInfo.STRING,
+                MMJDBCSQLTypeInfo.STRING, 
+                MMJDBCSQLTypeInfo.STRING,
+                MMJDBCSQLTypeInfo.SHORT                
+        };       
+        return createEmptyResultSet(columnNames, dataTypes);
+    }
+    
+    /**
+     * <p>Gets the URL used to connect to metamatrix
+     * @return URL used to connect.
+     * @throws SQLException
+     */
+    public String getURL() throws SQLException {
+        return driverConnection.getUrl();
+    }
+
+    /**
+     * <p>Gets the user name as known to metamatrix
+     * @return name if the user.
+     */
+    public String getUserName() throws SQLException {
+        return driverConnection.getUserName();
+    }
+
+    /**
+     * <p>Gets the description of the columns in a table that are automatically updated
+     * when any value in a row is updated. The column descriptions are not ordered.
+     * @param name of the catalog in which the table is present.
+     * @param name of the schema in which the table is present.
+     * @param name of the table which has the version columns.
+     * @return ResultSet object containing version column information.
+     * @throws SQLException, should never occur
+     */
+    public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
+        
+        // ResultSet returned has the same columns as best row identifier
+        // Method not supported, retuning empty ResultSet
+        ResultSet resultSet = getBestRowIdentifier(catalog, schema, table, 0, true);
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getVersionCols_success")); //$NON-NLS-1$
+
+       return resultSet;
+    }
+
+
+    /**
+     * <p>Checks whether a catalog name appears at the start of a fully qualified table
+     * name. If it is not at the beginning, it appears at the end.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean isCatalogAtStart() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether or not a visible row insert can be detected
+     * by calling ResultSet.rowInserted().</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return true if changes are detected by the resultset type
+     * @throws SQLException, should never occur
+     */
+    public boolean insertsAreDetected(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether the databases used by metamatrix are in read-only mode</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean isReadOnly() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether updates made to a LOB are made on a copy or directly to the LOB. </p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean locatorsUpdateCopy() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether the concatenation of a NULL vaule and a non-NULL value results
+     * in a NULL value.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean nullPlusNonNullIsNull() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether NULL vaules are sorted at the end regardless of sort order.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean nullsAreSortedAtEnd() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether NULL vaules are sorted at the start regardless of sort order.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean nullsAreSortedAtStart() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether NULL vaules are sorted high.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean nullsAreSortedHigh() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether NULL vaules are sorted low.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean nullsAreSortedLow() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Indicates whether a result set's own updates are visible.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return <code>true</code> if updates are visible for the result set type;
+     *        <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean ownUpdatesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether a result set's own deletes are visible.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return <code>true</code> if deletes are visible for the result set type;
+     *        <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean ownDeletesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether a result set's own inserts are visible.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return <code>true</code> if inserts are visible for the result set type;
+     *        <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean ownInsertsAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether updates made by others are visible.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return <code>true</code> if updates made by others
+     * are visible for the result set type;
+     *        <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean othersUpdatesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether deletes made by others are visible.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return <code>true</code> if deletes made by others
+     * are visible for the result set type;
+     *        <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean othersDeletesAreVisible(int type) throws SQLException {
+        return false;
+    }
+    /**
+     * <p>Indicates whether inserts made by others are visible.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return true if updates are visible for the result set type <code>true</code>
+     * if inserts made by others are visible for the result set type;
+     * <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean othersInsertsAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>This method checks whether metamatrix treats mixed-case unquoted SQL identifiers
+     * used in SQL statements as case-insensitive and stores them as all lowercase
+     * in its metadata tables.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean storesLowerCaseIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>This method checks whether metamatrix treats mixed-case quoted SQL identifiers
+     * used in SQL statements as case-insensitive and stores them as all lowercase
+     * in its metadata tables.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>This method checks whether metamatrix treats mixed-case unquoted SQL identifiers
+     * used in SQL statements as case-insensitive and stores them as all mixedcase
+     * in its metadata tables.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean storesMixedCaseIdentifiers() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>This method checks whether metamatrix treats mixed-case quoted SQL identifiers
+     * used in SQL statements as case-insensitive and stores them in mixedcase
+     * in its metadata tables.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>This method checks whether metamatrix treats mixed-case unquoted SQL identifiers
+     * used in SQL statements as case-insensitive and stores them as all uppercase
+     * in its metadata tables.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean storesUpperCaseIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>This method checks whether metamatrix treats mixed-case quoted SQL identifiers
+     * used in SQL statements as case-insensitive and stores them as all uppercase
+     * in its metadata tables.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ALTER TABLE with add column.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsAlterTableWithAddColumn() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ALTER TABLE with drop column.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsAlterTableWithDropColumn() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ANSI-92 entry level SQL grammer.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ANSI-92 full SQL grammer.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsANSI92FullSQL() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ANSI-92 intermediate SQL grammer.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsANSI92IntermediateSQL() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Indicates whether the driver supports batch updates.</p>
+     * @return true if the driver supports batch updates; false otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean supportsBatchUpdates() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a catalog name in a data manipulation
+     * statement.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCatalogsInDataManipulation() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a catalog name in an index definition
+     * statement.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a catalog name in a privilage
+     * definition statement.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a catalog name in a procedure call
+     * statement.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a catalog name in a table definition
+     * statement.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports column aliasing. If true the SQL AS clause
+     * can be used to provide names for alias names for columns.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsColumnAliasing() throws SQLException {
+        return true;
+   }
+
+    /**
+     * <p>Checks whether metamatrix supports scalar function CONVERT for the conversion
+     * of one JDBC type to another.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsConvert() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports scalar function CONVERT for the conversion
+     * of fromType to toType.</p>
+     * @param fromType SQL type from which to convert
+     * @param toType SQL type to convert to
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsConvert(int fromType, int toType) throws SQLException {
+    	String fromName = MMJDBCSQLTypeInfo.getTypeName(fromType);
+    	String toName = MMJDBCSQLTypeInfo.getTypeName(toType);
+    
+    	if (fromName.equals(toName)) {
+    		if (fromName.equals(DataTypeManager.DefaultDataTypes.OBJECT) && fromName != toName) {
+    			return false;
+    		}
+    		return true;
+    	}
+    	return DataTypeManager.isTransformable(fromName, toName);
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports correlated subqueries.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCorrelatedSubqueries() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ODBC Core SQL grammer.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsCoreSQLGrammar() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatric supports both data definition and data manipulation
+     * statements within a transaction.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Are only data manipulation statements within a transaction
+     * supported?</p>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatric supports only data manipulation statements within
+     * a transaction.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports expressions in ORDER BY lists.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsExpressionsInOrderBy() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports ODBC Extended SQL grammer.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsExtendedSQLGrammar() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports full outer joins</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsFullOuterJoins() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether auto-generated keys can be retrieved after a
+     * statement has been executed.
+     * @return boolean true if auto-generated keys can be retrieved
+     * after a statement has executed; false otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean supportsGetGeneratedKeys() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports GROUP BY</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsGroupBy() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether a GROUP BY clause can use columns that are not in the SELECT
+     * clause, provided that it specifies all the columns in the SELECT clause.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsGroupByBeyondSelect() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether a GROUP BY clause can use columns that are not in the SELECT
+     * clause.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsGroupByUnrelated() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports the SQL Integrity Enhancement Facility.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports specifying a LIKE escape clause.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsLikeEscapeClause() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix provides limited support for outer joins.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsLimitedOuterJoins() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports the ODBC minimum SQL grammer.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsMinimumSQLGrammar() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether mixed-case unquoted SQL identifiers used in SQL statements are
+     * case sensitive</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsMixedCaseIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether mixed-case quoted SQL identifiers used in SQL statements are
+     * case sensitive</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports having cursors open across commits.
+     * @return if so return true, else false.</p>
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Are multiple ResultSets from a single execute supported?</p>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean supportsMultipleResultSets() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether it is possible to have multiple ResultSet objects
+     * returned from a CallableStatement object simultaneously.
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean supportsMultipleOpenResults() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether multiple transactions open at once on different connectons</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsMultipleTransactions() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether metamatrix supports named parameters to callable statements.
+     * @return boolean true if named parameters are supported; false otherwise.
+     * @throws SQLException, should never occur
+     */
+    public boolean supportsNamedParameters() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports defining columns as nonnullable.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsNonNullableColumns() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports having cursors open across rollbacks.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports having cursors open across commits.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports having cursors open across rollbacks.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether an ORDER BY clause can use columns that are not in the SELECT clause.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsOrderByUnrelated() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports some form of outer joins.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsOuterJoins() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports positioned DELETEs on resultsets</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsPositionedDelete() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports positioned UPDATEs on result sets.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsPositionedUpdate() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Does the database support the concurrency type in combination
+     * with the given result set type?</p>
+     * @param type defined in <code>java.sql.ResultSet</code>
+     * @param concurrency type defined in <code>java.sql.ResultSet</code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     * @see Connection
+     */
+    public boolean supportsResultSetConcurrency(int type, int concurrency)
+      throws SQLException {
+        if(type == java.sql.ResultSet.TYPE_FORWARD_ONLY || type == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
+            if(concurrency == java.sql.ResultSet.CONCUR_READ_ONLY) {
+                return true;
+              }
+              return false;
+        }
+        return false;
+    }
+
+    /**
+     * Retrieves whether database supports the given result set holdability.
+     * Holdability - one of the following constants:
+     * ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT.
+     * @param intValue holdability
+     * @return boolean true if so; false otherwise
+     * @throws SQLException, should never occur
+
+     */
+    public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Does the database support the given result set type?</p>
+     * @param type defined in <code>java.sql.ResultSet</code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     * @see Connection
+     */
+    public boolean supportsResultSetType(int type) throws SQLException {
+
+        if(type == java.sql.ResultSet.TYPE_FORWARD_ONLY || type == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Retrieves whether metamatrix supports savepoints.
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSavepoints() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a schema name in a data manipulation
+     * statement</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSchemasInDataManipulation() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a schema name in an index definition
+     * statement</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a schema name in a privilage
+     * definition statement</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a schema name in an procedure
+     * call statement</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSchemasInProcedureCalls() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports using a schema name in an table
+     * definition statement</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSchemasInTableDefinitions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports SELECT FOR UPDATE statements</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSelectForUpdate() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this metamatrix supports statement pooling.
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsStatementPooling() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports stored procedure calls using the stored
+     * procedure escape syntax</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsStoredProcedures() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports subqueries in comparision expressions.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSubqueriesInComparisons() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports subqueries in EXISTS expressions.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSubqueriesInExists() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports subqueries in IN statements.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSubqueriesInIns() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports subqueries in qualified expressions.</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports table correlation names</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsTableCorrelationNames() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports the given transaction isolation level</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports transactions</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsTransactions() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports SQL UNION</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsUnion() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Checks whether metamatrix supports SQL UNION ALL</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean supportsUnionAll() throws SQLException {
+        return true;
+    }
+
+    /**
+     * <p>Indicates whether or not a visible row update can be detected by
+     * calling the method <code>ResultSet.rowUpdated</code>.</p>
+     * @param result set type, i.e. ResultSet.TYPE_XXX
+     * @return <code>true</code> if changes are detected by the result set type;
+     *         <code>false</code> otherwise
+     * @throws SQLException, should never occur
+     */
+    public boolean updatesAreDetected(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix uses a separate local file to store each table</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean usesLocalFilePerTable() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>Checks whether metamatrix stores tables in a local file</p>
+     * @return if so return true, else false.
+     * @throws SQLException, should never occur.
+     */
+    public boolean usesLocalFiles() throws SQLException {
+        return false;
+    }
+
+    /**
+     * <p>This method is used to produce ResultSets from server's Results objects for
+     * getCrossReference, getExportedKeys and getImportedKeys methods.
+     * @param server's Results object.
+     * @return ResultSet object giving the reference key info.
+     * @throws SQLException if there is an accesing server results
+     */
+    private ResultSet getReferenceKeys(ResultSetImpl results) throws SQLException {
+
+        // list which represent records containing reference key info
+        List records = new ArrayList ();
+        ResultSetMetaData rmetadata = null;
+        try {
+            // build the list of records from Results object.
+            while (results.next()) {
+                // list represents a record on the Results object.
+                List currentRow = new ArrayList (15);
+                // add values in the current record on the Results object to the list
+                // number of values to be fetched from each row is MAX_COLUMNS.
+                for(int i=0; i < JDBCColumnPositions.REFERENCE_KEYS.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                // add the current row to the list of records.
+                records.add(currentRow);
+            }// end of while
+
+            // get the metadata for the results
+            rmetadata = results.getMetaData();
+
+        } catch (Exception e) {
+            String msg = JDBCPlugin.Util.getString("MMDatabaseMetadata.Err_getting_primary_keys"); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, msg);
+        }
+
+        // close the resultset and driver connection
+        //results.close();
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getRefKey_success")); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+    }
+
+    /**
+     * <p>This method is used to hardcode metadata details for a given column into
+     * a map object. While some of the details are obtained as parameters, most
+     * are hardcoded.
+     * @param tableName The group/table name in which the column is present
+     * @param columnName The name of the column/element
+     * @param dataType The MetaMatrix datatype of the column
+     * @param nullable An int value indicating nallability of the column
+     * @return a map containing metadata details for any given column
+     * @throws SQLException, should never occur
+     */
+    private Map getColumnMetadata(String tableName, String columnName, String dataType, Integer nullable) throws SQLException {
+            return getColumnMetadata(tableName, columnName, dataType, nullable, ResultsMetadataConstants.SEARCH_TYPES.UNSEARCHABLE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE);
+    }
+    
+    private Map getColumnMetadata(String tableName, String columnName, String dataType, Integer nullable, Integer searchable, Boolean writable, Boolean signed, Boolean caseSensitive) throws SQLException {
+
+        // map that would contain metadata details
+        Map metadataMap = new HashMap();
+
+        /*******************************************************
+         HardCoding Column metadata details for the given column
+        ********************************************************/
+
+        metadataMap.put(ResultsMetadataConstants.VIRTUAL_DATABASE_NAME, driverConnection.getVDBName());
+        metadataMap.put(ResultsMetadataConstants.GROUP_NAME, tableName);
+        metadataMap.put(ResultsMetadataConstants.ELEMENT_NAME, columnName);
+        metadataMap.put(ResultsMetadataConstants.DATA_TYPE, dataType);
+        metadataMap.put(ResultsMetadataConstants.PRECISION, ResultsMetadataDefaults.getDefaultPrecision(dataType));
+        metadataMap.put(ResultsMetadataConstants.RADIX, new Integer(10));
+        metadataMap.put(ResultsMetadataConstants.SCALE, new Integer(0));
+        metadataMap.put(ResultsMetadataConstants.AUTO_INCREMENTING, Boolean.FALSE);
+        metadataMap.put(ResultsMetadataConstants.CASE_SENSITIVE, caseSensitive);
+        metadataMap.put(ResultsMetadataConstants.NULLABLE, nullable);
+        metadataMap.put(ResultsMetadataConstants.SEARCHABLE, searchable);
+        metadataMap.put(ResultsMetadataConstants.SIGNED, signed);
+        metadataMap.put(ResultsMetadataConstants.WRITABLE, writable);
+        metadataMap.put(ResultsMetadataConstants.CURRENCY, Boolean.FALSE);
+        metadataMap.put(ResultsMetadataConstants.DISPLAY_SIZE, ResultsMetadataDefaults.getMaxDisplaySize(dataType));
+
+        return metadataMap;
+    }
+
+	public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+		return false;
+	}
+
+	public int getResultSetHoldability() throws SQLException {
+		return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+	}
+	
+	public Connection getConnection() throws SQLException {
+		return driverConnection;
+	}
+	
+	public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+		return false;
+	}
+
+	public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public ResultSet getClientInfoProperties() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public ResultSet getFunctionColumns(String catalog, String schemaPattern,
+			String functionNamePattern, String columnNamePattern)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public ResultSet getFunctions(String catalog, String schemaPattern,
+			String functionNamePattern) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public RowIdLifetime getRowIdLifetime() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public ResultSet getSchemas(String catalog, String schemaPattern)
+			throws SQLException {
+		if (catalog == null) {
+            catalog = PERCENT;
+        }
+        
+        if (schemaPattern == null) {
+            schemaPattern = PERCENT;
+        }
+        // list which represent records containing schema info
+        List records = new ArrayList ();
+
+        ResultSetMetaData rmetadata = null;
+        ResultSetImpl results = null;
+        PreparedStatement prepareQuery = null;
+        try {
+            prepareQuery = driverConnection.prepareStatement(QUERY_SCHEMAS);
+            prepareQuery.setObject(1, catalog.toUpperCase());
+            prepareQuery.setObject(2, schemaPattern.toUpperCase());
+            // make a query against runtimemetadata and get results
+            results = (ResultSetImpl) prepareQuery.executeQuery();
+
+            while (results.next ()) {
+                // each row will have only one column(Virtual database name)
+                List currentRow = new ArrayList (2);
+
+                for(int i = 0; i < JDBCColumnPositions.SCHEMAS.MAX_COLUMNS; i++) {
+                    // get the value at the current index add it to currentRow
+                    currentRow.add(results.getObject(i+1));
+                }
+
+                records.add(currentRow);
+            }
+
+            // Get the metadata for the results
+            rmetadata = results.getMetaData();
+
+        } catch(Exception e) {
+            throw TeiidSQLException.create(e, JDBCPlugin.Util.getString("MMDatabaseMetadata.getschema_error", e.getMessage())); //$NON-NLS-1$
+        }
+
+        logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getschema_success")); //$NON-NLS-1$
+
+        // construct results object from column values and their metadata
+        return createResultSet(records, rmetadata);
+	}
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.teiid.client.metadata.MetadataResult;
+import org.teiid.client.metadata.ResultsMetadataConstants;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.core.util.StringUtil;
+
+/**
+ * This metadata provider starts with just column names and types (provided in the response)
+ * but must lazily load the rest of the metadata when necessary.
+ */
+public class DeferredMetadataProvider extends MetadataProvider {
+    private StatementImpl statement;
+    private long requestID;
+
+    public DeferredMetadataProvider(String[] columnNames, String[] columnTypes, StatementImpl statement, long requestID) {
+        super(loadPartialMetadata(columnNames, columnTypes));
+        this.statement = statement;
+        this.requestID = requestID;
+    }
+    
+    static Map[] loadPartialMetadata(String[] columnNames, String[] columnTypes) {
+    	if(columnNames == null || columnTypes == null || columnNames.length != columnTypes.length) {
+            Object[] params = new Object[] { 
+                StringUtil.toString(columnNames), StringUtil.toString(columnTypes)
+            };
+            throw new IllegalArgumentException(JDBCPlugin.Util.getString("DeferredMetadataProvider.Invalid_data", params)); //$NON-NLS-1$
+        }
+        Map[] columnMetadata = new Map[columnNames.length];
+        for(int i=0; i<columnNames.length; i++) {
+            columnMetadata[i] = new HashMap();
+            columnMetadata[i].put(ResultsMetadataConstants.ELEMENT_NAME, columnNames[i]);
+            columnMetadata[i].put(ResultsMetadataConstants.DATA_TYPE, columnTypes[i]);
+        }
+        return columnMetadata;
+    }
+
+    private void loadFullMetadata() throws SQLException {
+    	MetadataResult results;
+		try {
+			results = this.statement.getDQP().getMetadata(this.requestID);
+		} catch (MetaMatrixComponentException e) {
+			throw TeiidSQLException.create(e);
+		} catch (MetaMatrixProcessingException e) {
+			throw TeiidSQLException.create(e);
+		}
+        this.metadata = results.getColumnMetadata();
+    }
+
+    @Override
+    public Object getValue(int columnIndex, Integer metadataPropertyKey) throws SQLException {
+        Object value = super.getValue(columnIndex, metadataPropertyKey);
+        
+        if(value == null) {
+            loadFullMetadata();
+            value = super.getValue(columnIndex, metadataPropertyKey);          
+        }
+        
+        return value;
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/EmbeddedProfile.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+import org.teiid.net.ServerConnection;
+
+import com.metamatrix.common.util.PropertiesUtils;
+import com.metamatrix.core.MetaMatrixCoreException;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+import com.metamatrix.core.util.ReflectionHelper;
+
+final class EmbeddedProfile {
+    
+	/** 
+     * Match URL like
+     * - jdbc:teiid:BQT
+     * - jdbc:teiid:BQT;verson=1  
+     */
+    static final String BASE_PATTERN = "jdbc:teiid:((\\w+)[;]?)(;([^@])+)*"; //$NON-NLS-1$
+
+    private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+    
+    static Pattern basePattern = Pattern.compile(BASE_PATTERN);
+    
+    /**
+     * This method tries to make a connection to the given URL. This class
+     * will return a null if this is not the right driver to connect to the given URL.
+     * @param The URL used to establish a connection.
+     * @return Connection object created
+     * @throws SQLException if it is unable to establish a connection
+     */
+    public static Connection connect(String url, Properties info) 
+        throws SQLException {
+        // create a properties obj if it is null
+        if (info == null) {
+            info = new Properties();
+        } else {
+        	info = PropertiesUtils.clone(info);
+        }
+
+        // parse the URL to add it's properties to properties object
+        parseURL(url, info);            
+        ConnectionImpl conn = createConnection(url, info);
+        logger.fine(JDBCPlugin.Util.getString("JDBCDriver.Connection_sucess")); //$NON-NLS-1$ 
+        return conn;
+    }
+    
+    static ConnectionImpl createConnection(String url, Properties info) throws SQLException{
+        
+        // first validate the properties as this may called from the EmbeddedDataSource
+        // and make sure we have all the properties we need.
+        validateProperties(info);
+        try {
+        	ServerConnection sc = (ServerConnection)ReflectionHelper.create("org.teiid.transport.LocalServerConnection", Arrays.asList(info), Thread.currentThread().getContextClassLoader()); //$NON-NLS-1$
+			return new ConnectionImpl(sc, info, url);
+		} catch (MetaMatrixRuntimeException e) {
+			throw TeiidSQLException.create(e);
+		} catch (ConnectionException e) {
+			throw TeiidSQLException.create(e);
+		} catch (CommunicationException e) {
+			throw TeiidSQLException.create(e);
+		} catch (MetaMatrixCoreException e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+    
+    /**
+     * This method parses the URL and adds properties to the the properties object. These include required and any optional
+     * properties specified in the URL. 
+     * Expected URL format -- 
+     * jdbc:teiid:VDB;[name=value]*;
+     * 
+     * @param The URL needed to be parsed.
+     * @param The properties object which is to be updated with properties in the URL.
+     * @throws SQLException if the URL is not in the expected format.
+     */
+     static void parseURL(String url, Properties info) throws SQLException {
+        if (url == null || url.trim().length() == 0) {
+            String logMsg = JDBCPlugin.Util.getString("EmbeddedDriver.URL_must_be_specified"); //$NON-NLS-1$
+            throw new SQLException(logMsg);
+        }
+                
+        try {
+            JDBCURL jdbcURL = new JDBCURL(url);
+
+            // Set the VDB Name
+            info.setProperty(BaseDataSource.VDB_NAME, jdbcURL.getVDBName());
+                       
+            Properties optionalParams = jdbcURL.getProperties();
+            JDBCURL.normalizeProperties(info);
+            
+            Enumeration keys = optionalParams.keys();
+            while (keys.hasMoreElements()) {
+                String propName = (String)keys.nextElement();
+                // Don't let the URL properties override the passed-in Properties object.
+                if (!info.containsKey(propName)) {
+                    info.setProperty(propName, optionalParams.getProperty(propName));
+                }
+            }
+            // add the property only if it is new because they could have
+            // already been specified either through url or otherwise.
+            if(! info.containsKey(BaseDataSource.VDB_VERSION) && jdbcURL.getVDBVersion() != null) {
+                info.setProperty(BaseDataSource.VDB_VERSION, jdbcURL.getVDBVersion());
+            }
+            if(!info.containsKey(BaseDataSource.APP_NAME)) {
+                info.setProperty(BaseDataSource.APP_NAME, BaseDataSource.DEFAULT_APP_NAME);
+            }
+        } catch (Exception e) {
+            throw new SQLException(e); 
+        }        
+    }
+
+    /** 
+     * validate some required properties 
+     * @param info the connection properties to be validated
+     * @throws SQLException
+     * @since 4.3
+     */
+    static void validateProperties(Properties info) throws SQLException {
+        // VDB Name has to be there
+        String value = null;
+        value = info.getProperty(BaseDataSource.VDB_NAME);
+        if (value == null || value.trim().length() == 0) {
+            String logMsg = JDBCPlugin.Util.getString("MMDataSource.Virtual_database_name_must_be_specified"); //$NON-NLS-1$
+            throw new SQLException(logMsg);
+        }
+
+    }
+    
+    public static boolean acceptsURL(String url) {
+        // Check if this can match our default one, then allow it.
+        Matcher m = basePattern.matcher(url);
+        boolean matched = m.matches();
+        return matched;
+    }    
+    
+}


Property changes on: trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ExecutionProperties.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import org.teiid.client.RequestMessage;
+
+/**
+ * MetaMatrix-specific execution properties.  These execution properties can 
+ * be set via the {@link com.metamatrix.jdbc.api.Statement#setExecutionProperty(String, String)}
+ * method.  They affect the subsequent execution of all commands on that Statement
+ * instance.   
+ */
+public interface ExecutionProperties {
+
+    /** Execution property name for XML format */
+    public static final String PROP_XML_FORMAT = "XMLFormat"; //$NON-NLS-1$
+    
+    /** Execution property name for XML validation */
+    public static final String PROP_XML_VALIDATION = "XMLValidation"; //$NON-NLS-1$
+
+    /** Execution property name for transaction auto wrap mode */
+    public static final String PROP_TXN_AUTO_WRAP = "autoCommitTxn"; //$NON-NLS-1$
+
+    /** Execution property name for partial results mode */
+    public static final String PROP_PARTIAL_RESULTS_MODE = "partialResultsMode"; //$NON-NLS-1$
+
+    /** XML results format:  XML results displayed as a formatted tree */
+    public static final String XML_TREE_FORMAT = "Tree"; //$NON-NLS-1$
+
+    /** XML results format:  XML results displayed in compact form */
+    public static final String XML_COMPACT_FORMAT = "Compact"; //$NON-NLS-1$
+
+    /** Transaction auto wrap constant - never wrap a command execution in a transaction */
+    public static final String TXN_WRAP_OFF = RequestMessage.TXN_WRAP_OFF;
+
+    /** Transaction auto wrap constant - always wrap commands in a transaction. */
+    public static final String TXN_WRAP_ON = RequestMessage.TXN_WRAP_ON;
+
+    /**
+     * Transaction auto wrap constant - checks if a command
+     * requires a transaction and will be automatically wrap it.
+     */
+    public static final String TXN_WRAP_DETECT = RequestMessage.TXN_WRAP_DETECT;
+
+    /** 
+     * Whether to use result set cache if it is available 
+     * @since 4.2 
+     */
+    public static final String RESULT_SET_CACHE_MODE = "resultSetCacheMode"; //$NON-NLS-1$
+    
+    /**
+     * Default fetch size to use on Statements if the fetch size is not explicitly set.
+     * The default is 500.  
+     * @since 4.2
+     */
+    public static final String PROP_FETCH_SIZE = "fetchSize";   //$NON-NLS-1$ 
+    
+    /**
+     * If true, will ignore autocommit for local transactions.
+     * @since 5.5.2
+     */
+    public static final String DISABLE_LOCAL_TRANSACTIONS = "disableLocalTxn";  //$NON-NLS-1$
+    
+    /**
+	 * Overrides the handling of double quoted identifiers to allow them to be strings.
+	 * @since 4.3 
+     */
+    public static final String ANSI_QUOTED_IDENTIFIERS = "ansiQuotedIdentifiers"; //$NON-NLS-1$   
+    
+    /**
+     * Additional options/hints for executing the command
+     * @since 4.3
+     */
+    public static final String PROP_SQL_OPTIONS = "sqlOptions"; //$NON-NLS-1$
+    
+    /**
+     * Passed as an option to PROP_SQL_OPTIONS
+     */
+    public static final String SQL_OPTION_SHOWPLAN = "SHOWPLAN"; //$NON-NLS-1$
+    
+}
+    
\ No newline at end of file

Copied: trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,155 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+
+/**
+ */
+public class FilteredResultsMetadata extends WrapperImpl implements ResultSetMetaData {
+
+    private ResultSetMetaData delegate; 
+    private int actualColumnCount;
+    
+    static FilteredResultsMetadata newInstance (ResultSetMetaData rsmd, int actualColumnCount) {
+        return new FilteredResultsMetadata(rsmd, actualColumnCount);
+    }    
+    
+    FilteredResultsMetadata(ResultSetMetaData rsmd, int actualColumnCount) {
+        this.delegate = rsmd;
+        this.actualColumnCount = actualColumnCount;
+    }
+    
+    public int getColumnCount() throws SQLException {
+        return actualColumnCount;
+    }
+    
+    private void verifyColumnIndex(int index) throws SQLException {
+        if(index > actualColumnCount) {
+            throw new SQLException(JDBCPlugin.Util.getString("FilteredResultsMetadata.Invalid_index", index)); //$NON-NLS-1$
+        }
+    }
+
+    public boolean isAutoIncrement(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isAutoIncrement(column);
+    }
+
+    public boolean isCaseSensitive(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isCaseSensitive(column);
+    }
+
+    public boolean isSearchable(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isSearchable(column);
+    }
+
+    public boolean isCurrency(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isCurrency(column);
+    }
+
+    public int isNullable(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isNullable(column);
+    }
+
+    public boolean isSigned(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isSigned(column);
+    }
+
+    public int getColumnDisplaySize(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getColumnDisplaySize(column);
+    }
+
+    public String getColumnLabel(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getColumnLabel(column);
+    }
+
+    public String getColumnName(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getColumnName(column);
+    }
+
+    public String getSchemaName(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getSchemaName(column);
+    }
+
+    public int getPrecision(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getPrecision(column);
+    }
+
+    public int getScale(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getScale(column);
+    }
+
+    public String getTableName(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getTableName(column);
+    }
+
+    public String getCatalogName(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getCatalogName(column);
+    }
+
+    public int getColumnType(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getColumnType(column);
+    }
+
+    public String getColumnTypeName(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getColumnTypeName(column);
+    }
+
+    public boolean isReadOnly(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isReadOnly(column);
+    }
+
+    public boolean isWritable(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isWritable(column);
+    }
+
+    public boolean isDefinitelyWritable(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.isDefinitelyWritable(column);
+    }
+
+    public String getColumnClassName(int column) throws SQLException {
+        verifyColumnIndex(column);
+        return this.delegate.getColumnClassName(column);
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCColumnNames.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,596 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+/* <p> This class contains constants indicating names of the columns in the
+ *  result sets returned by methods on DatabaseMetaData. Each inner class represents
+ *  a particular method and the class attributes give the names of the columns on
+ *  methods ResultSet.</p>
+ */
+
+interface JDBCColumnNames {
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getCatalogs method on DatabaseMetaData. These constant values
+     * are be used for the column names used in constructing the ResultSet obj.
+     */
+    interface CATALOGS {
+        //  name of the column containing catalog or Virtual database name.
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getColumns method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface COLUMNS {
+
+        //  name of the column containing catalog or Virtual database name.
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+        //  name of the column containing schema or Virtual database version.
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+        //  name of the column containing table or group name.
+        static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+        //  name of the column containing column or element name.
+        static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+        /** name of column that contains SQL type from java.sql.Types for column's data type. */
+        static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+        /** name of column that contains local type name used by the data source. */
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+        //  name of the column containing column size.
+        static final String COLUMN_SIZE = "COLUMN_SIZE"; //$NON-NLS-1$
+
+        /** name of column that is not used will contain nulls */
+        static final String BUFFER_LENGTH = "BUFFER_LENGTH"; //$NON-NLS-1$
+
+        //  name of the column containing number of digits to right of decimal
+        static final String DECIMAL_DIGITS = "DECIMAL_DIGITS"; //$NON-NLS-1$
+
+        //  name of the column containing column's Radix.
+        static final String NUM_PREC_RADIX = "NUM_PREC_RADIX"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating nullablity */
+        static final String NULLABLE = "NULLABLE"; //$NON-NLS-1$
+
+        /** name of column containing explanatory notes. */
+        static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+
+        /** name of column which contails default value for the column. */
+        static final String COLUMN_DEF = "COLUMN_DEF"; //$NON-NLS-1$
+
+        /** name of column that not used will contain nulls */
+        static final String SQL_DATA_TYPE = "SQL_DATA_TYPE"; //$NON-NLS-1$
+
+        /** name of column that not used will contain nulls */
+        static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB"; //$NON-NLS-1$
+
+        /** name of column that stores the max number of bytes in the column */
+        static final String CHAR_OCTET_LENGTH = "CHAR_OCTET_LENGTH"; //$NON-NLS-1$
+
+        /** name of column that stores the index of a column in the table */
+        static final String ORDINAL_POSITION = "ORDINAL_POSITION"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating nullablity */
+        static final String IS_NULLABLE = "IS_NULLABLE"; //$NON-NLS-1$
+
+        /** name of column that is the scope of a reference attribute (null if DATA_TYPE isn't REF)*/ 
+        static final String SCOPE_CATLOG = "SCOPE_CATLOG"; //$NON-NLS-1$
+        
+        /** name of column that is the scope of a reference attribute (null if the DATA_TYPE isn't REF) */ 
+        static final String SCOPE_SCHEMA = "SCOPE_SCHEMA"; //$NON-NLS-1$
+        
+        /** name of column that is the scope of a reference attribure (null if the DATA_TYPE isn't REF) */
+        static final String SCOPE_TABLE = "SCOPE_TABLE"; //$NON-NLS-1$
+        
+        /** 
+         * name of column that is source type of a distinct type or user-generated Ref type, SQL type
+         * from java.sql.Types (null if DATA_TYPE isn't DISTINCT or user-generated REF)
+         */ 
+        static final String SOURCE_DATA_TYPE = "SOURCE_DATA_TYPE"; //$NON-NLS-1$
+        
+        /** name of column that has an String value indicating format */
+        static final String FORMAT = "FORMAT"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating minimum range */
+        static final String MIN_RANGE = "MIN_RANGE"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating maximum range */
+        static final String MAX_RANGE = "MAX_RANGE"; //$NON-NLS-1$
+     }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getColumnPrivileges and getTablePrivileges methods on
+     * DatabaseMetaData. These constant values are be used to hardcode the column
+     * names used in constructin the ResultSet obj.
+     */
+    interface PRIVILEGES {
+
+        //  name of the column containing catalog or Virtual database name.
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+        //  name of the column containing schema or Virtual database version.
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+        //  name of the column containing table or group name.
+        static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+        //  name of the column containing column or element name.
+        static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+        //  name of the column containing Grantor name
+        static final String GRANTOR = "GRANTOR"; //$NON-NLS-1$
+
+        //  name of the column containing Grantee name
+        static final String GRANTEE = "GRANTEE"; //$NON-NLS-1$
+
+        //  name of the column containing privilege name
+        static final String PRIVILEGE = "PRIVILEGE"; //$NON-NLS-1$
+
+        //  name of the column containing privilage grantable info
+        static final String IS_GRANTABLE = "IS_GRANTABLE"; //$NON-NLS-1$
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getCrossReference, getExportedKeys, and getImportedKeys methods
+     * on DatabaseMetaData. These constant values are be used to hardcode the
+     * column names used in constructin the ResultSet obj.
+     */
+    interface REFERENCE_KEYS {
+
+        //  name of the column containing catalog or Virtual database name for primary key's table.
+        static final String PKTABLE_CAT = "PKTABLE_CAT"; //$NON-NLS-1$
+
+        //  name of the column containing schema or Virtual database version for primary key's table.
+        static final String PKTABLE_SCHEM = "PKTABLE_SCHEM"; //$NON-NLS-1$
+
+        //  name of the column containing table or group name for primary key's table.
+        static final String PKTABLE_NAME = "PKTABLE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing column or element name of the primary key.
+        static final String PKCOLUMN_NAME = "PKCOLUMN_NAME"; //$NON-NLS-1$
+
+        // name of the column containing catalog or Virtual database name for foreign key's table.
+        static final String FKTABLE_CAT = "FKTABLE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version for foreign key's table.
+        static final String FKTABLE_SCHEM = "FKTABLE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing table or group name for foreign key's table.
+        static final String FKTABLE_NAME = "FKTABLE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing column or element name of the foreign key.
+        static final String FKCOLUMN_NAME = "FKCOLUMN_NAME"; //$NON-NLS-1$
+
+        // name of the column containing sequence number within the foreign key
+        static final String KEY_SEQ = "KEY_SEQ"; //$NON-NLS-1$
+
+        // name of the column containing effect on foreign key when PK is updated.
+        static final String UPDATE_RULE = "UPDATE_RULE"; //$NON-NLS-1$
+
+        // name of the column containing effect on foreign key when PK is deleted.
+        static final String DELETE_RULE = "DELETE_RULE"; //$NON-NLS-1$
+
+        // name of the column containing name of the foreign key.
+        static final String FK_NAME = "FK_NAME"; //$NON-NLS-1$
+
+        // name of the column containing name of the primary key.
+        static final String PK_NAME = "PK_NAME"; //$NON-NLS-1$
+
+        // name of the column containing deferability of foreign key constraStrings.
+        static final String DEFERRABILITY = "DEFERRABILITY"; //$NON-NLS-1$
+        static final String FKPOSITION = "FKPOSITION"; //$NON-NLS-1$
+    }
+
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getPrimaryKeys method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface PRIMARY_KEYS {
+
+        // name of the column containing catalog or Virtual database name.
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version.
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing table or group name.
+        static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing column or element name.
+        static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+        // name of the column containing sequence number within the primary key
+        static final String KEY_SEQ = "KEY_SEQ"; //$NON-NLS-1$
+
+        // name of the column containing name of the primary key.
+        static final String PK_NAME = "PK_NAME"; //$NON-NLS-1$
+        static final String POSITION = "POSITION"; //$NON-NLS-1$
+    }
+
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getProcedureColumns method on DatabaseMetaData. These constant
+     * values are be used to hardcode the column names used in constructin the
+     * ResultSet obj.
+     */
+    interface PROCEDURE_COLUMNS {
+
+        // name of the column containing procedure catalog or Virtual database name.
+        static final String PROCEDURE_CAT = "PROCEDURE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version.
+        static final String PROCEDURE_SCHEM = "PROCEDURE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing table or group name.
+        static final String PROCEDURE_NAME = "PROCEDURE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing column or element name.
+        static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+        // name of the column containing column or element type.
+        static final String COLUMN_TYPE = "COLUMN_TYPE"; //$NON-NLS-1$
+
+        /** name of column that contains SQL type from java.sql.Types for column's data type. */
+        static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+        /** name of column that contains local type name used by the data source. */
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing number of digits to right of decimal
+        static final String PRECISION = "PRECISION"; //$NON-NLS-1$
+
+        /** name of column that that contains length of data in bytes */
+        static final String LENGTH = "LENGTH"; //$NON-NLS-1$
+
+        // constant indiacting column's Radix.
+        static final String SCALE = "SCALE";         //$NON-NLS-1$
+
+        // constant indiacting column's Radix.
+        static final String RADIX = "RADIX"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating nullablity */
+        static final String NULLABLE = "NULLABLE"; //$NON-NLS-1$
+
+        /** name of column containing explanatory notes. */
+        static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+        static final String POSITION = "POSITION"; //$NON-NLS-1$
+    }
+
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getProcedures method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface PROCEDURES {
+
+        // name of the column containing procedure catalog or Virtual database name.
+        static final String PROCEDURE_CAT = "PROCEDURE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version.
+        static final String PROCEDURE_SCHEM = "PROCEDURE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing table or group name.
+        static final String PROCEDURE_NAME = "PROCEDURE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing name of the column which is reserved
+        //static final String RESERVED = "RESERVED";
+
+        /** name of column containing explanatory notes. */
+        static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+
+        /** name of column indicating kind of the procedure. */
+        static final String PROCEDURE_TYPE = "PROCEDURE_TYPE"; //$NON-NLS-1$
+        
+        static final String RESERVED_1 = "RESERVED_1"; //$NON-NLS-1$
+        static final String RESERVED_2 = "RESERVED_2"; //$NON-NLS-1$
+        static final String RESERVED_3 = "RESERVED_3";   //$NON-NLS-1$
+    }
+
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getSchemas method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface SCHEMAS {
+
+        // name of the column containing procedure catalog or Virtual database name.
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version.
+        static final String TABLE_CATALOG = "TABLE_CATALOG"; //$NON-NLS-1$
+
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getTables and getTableTypes methods on DatabaseMetaData. These
+     * constant values are be used to hardcode the column names used in construction
+     * the ResultSet obj.
+     */
+    interface TABLES {
+
+        // name of the column containing catalog or Virtual database name.
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version.
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing table or group name.
+        static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing table or group type.
+        static final String TABLE_TYPE = "TABLE_TYPE"; //$NON-NLS-1$
+
+        /** name of column containing explanatory notes. */
+        static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+        static final String TYPE_CAT = "TYPE_CAT"; //$NON-NLS-1$
+        static final String TYPE_SCHEM = "TYPE_SCHEM"; //$NON-NLS-1$
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+        static final String SELF_REFERENCING_COL_NAME = "SELF_REFERENCING_COL_NAME"; //$NON-NLS-1$
+        static final String REF_GENERATION = "REF_GENERATION"; //$NON-NLS-1$
+        static final String ISPHYSICAL = "ISPHYSICAL"; //$NON-NLS-1$
+    
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getTables and getTableTypes methods on DatabaseMetaData. These
+     * constant values are be used to hardcode the column names used in construction
+     * the ResultSet obj.
+     */
+    interface TABLE_TYPES {
+
+        // name of the column containing table or group type.
+        static final String TABLE_TYPE = "TABLE_TYPE"; //$NON-NLS-1$
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getTypeInfo method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface TYPE_INFO {
+
+        /** name of column that contains local type name used by the data source. */
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+        /** name of column that contains SQL type from java.sql.Types for column's data type. */
+        static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+        // name of the column containing number of digits to right of decimal
+        static final String PRECISION = "PRECISION"; //$NON-NLS-1$
+
+        // name of the column containing prefix used to quote a literal
+        static final String LITERAL_PREFIX = "LITERAL_PREFIX"; //$NON-NLS-1$
+
+        // name of the column containing suffix used to quote a literal
+        static final String LITERAL_SUFFIX = "LITERAL_SUFFIX"; //$NON-NLS-1$
+
+        // name of the column containing params used in creating the type
+        static final String CREATE_PARAMS = "CREATE_PARAMS"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating nullablity */
+        static final String NULLABLE = "NULLABLE"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating case sensitivity */
+        static final String CASE_SENSITIVE = "CASE_SENSITIVE"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating searchability */
+        static final String SEARCHABLE = "SEARCHABLE"; //$NON-NLS-1$
+
+        /** name of column that has an String value indicating searchability */
+        static final String UNSIGNED_ATTRIBUTE = "UNSIGNED_ATTRIBUTE"; //$NON-NLS-1$
+
+        /** name of column that contains info if the column is a currency value */
+        static final String FIXED_PREC_SCALE = "FIXED_PREC_SCALE"; //$NON-NLS-1$
+
+        /** name of column that contains info whether the column is autoincrementable */
+        static final String AUTOINCREMENT = "AUTO_INCREMENT"; //$NON-NLS-1$
+
+        /** name of column that localised version of type name */
+        static final String LOCAL_TYPE_NAME = "LOCAL_TYPE_NAME"; //$NON-NLS-1$
+
+        /** name of column that gives the min scale supported */
+        static final String MINIMUM_SCALE = "MINIMUM_SCALE"; //$NON-NLS-1$
+
+        /** name of column that gives the max scale supported */
+        static final String MAXIMUM_SCALE = "MAXIMUM_SCALE"; //$NON-NLS-1$
+
+        /** name of column that not used will contain nulls */
+        static final String SQL_DATA_TYPE = "SQL_DATA_TYPE"; //$NON-NLS-1$
+
+        /** name of column that not used will contain nulls */
+        static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB"; //$NON-NLS-1$
+
+        // constant indiacting column's Radix.
+        static final String NUM_PREC_RADIX = "NUM_PREC_RADIX"; //$NON-NLS-1$
+    }
+
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getUDTS method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface UDTS {
+
+        // name of the column containing table or Groups name in which UDTS are present.
+        static final String TABLE_NAME = "UDTS"; //$NON-NLS-1$
+
+        // name of the column containing catalog or Virtual database name.
+        static final String TYPE_CAT = "TYPE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing schema or Virtual database version.
+        static final String TYPE_SCHEM = "TYPE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing name of type name column.
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing class name column.
+        static final String CLASS_NAME = "CLASS_NAME"; //$NON-NLS-1$
+
+        // name of the column containing name of sql datatype code column
+        static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+        // name of the column containing comments column
+        static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+        static final String BASE_TYPE = "BASE_TYPE"; //$NON-NLS-1$
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getIndexInfo method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface INDEX_INFO {
+
+        // name of the column containing tables catalog name on which the index is present
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+        // name of the column containing tables schema name on which the index is present
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+        // name of the column containing table or group name.
+        static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing name of column showing if an index in non-unique
+        static final String NON_UNIQUE = "NON_UNIQUE"; //$NON-NLS-1$
+
+        // name of the column containing name of column containing index_qualifier string
+        static final String INDEX_QUALIFIER = "INDEX_QUALIFIER"; //$NON-NLS-1$
+
+        // name of the column containing name of column containing index names
+        static final String INDEX_NAME = "INDEX_NAME"; //$NON-NLS-1$
+
+        // name of the column containing name of column containing index types
+        static final String TYPE = "TYPE"; //$NON-NLS-1$
+
+        // name of the column containing name of the column containing column position.
+        static final String ORDINAL_POSITION = "ORDINAL_POSITION"; //$NON-NLS-1$
+
+        // name of the column containing name of the column containing column names.
+        static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+        // name of the column containing name of column containing info if the index is asc or desc.
+        static final String ASC_OR_DESC = "ASC_OR_DESC"; //$NON-NLS-1$
+
+        // name of the column containing name of the column containing number of unique values in index.
+        static final String CARDINALITY = "CARDINALITY"; //$NON-NLS-1$
+
+        // name of the column containing name of the column giving number od pages used for the current index.
+        static final String PAGES = "PAGES"; //$NON-NLS-1$
+
+        // name of the column containing name of the column giving filter condition.
+        static final String FILTER_CONDITION = "FILTER_CONDITION"; //$NON-NLS-1$
+    }
+
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getBestRowIdentifier method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface BEST_ROW {
+
+        // name of the column containing SCOPE of the identifier
+        static final String SCOPE = "SCOPE"; //$NON-NLS-1$
+
+        // name of the column containing column name
+        static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+        // name of the column containing data type code
+        static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+        // name of the column containing data type name
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+        // name of the column containing size of the column
+        static final String COLUMN_SIZE = "COLUMN_SIZE"; //$NON-NLS-1$
+
+        // name of the column containing buffer length
+        static final String BUFFER_LENGTH = "BUFFER_LENGTH"; //$NON-NLS-1$
+
+        // name of the column containing decimal digits/ scale
+        static final String DECIMAL_DIGITS = "DECIMAL_DIGITS"; //$NON-NLS-1$
+
+        // name of the column containing name of the column containing column position.
+        static final String ORDINAL_POSITION = "ORDINAL_POSITION"; //$NON-NLS-1$
+
+        // name of the column containing pseudo column
+        static final String PSEUDO_COLUMN = "PSEUDO_COLUMN"; //$NON-NLS-1$
+    }
+    
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getSuperTables method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    interface SUPER_TABLES {
+        // name of the column containing catalog or Virtual database name.
+        static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+        // name of the column containing schema or Virtual database version.
+        static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+        // name of the column containing table or Groups name .
+        static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+        // name of the column containing super table.
+        static final String SUPERTABLE_NAME = "SUPERTABLE_NAME"; //$NON-NLS-1$
+    }
+    
+    /**
+     * This class contains constants representing column names on ResultSet
+     * returned by getSuperTypes method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column names used in constructin the ResultSet obj.
+     */
+    
+    interface SUPER_TYPES {
+
+        // name of the column containing catalog or Virtual database name.
+        static final String TYPE_CAT = "TYPE_CAT"; //$NON-NLS-1$
+        // name of the column containing schema or Virtual database version.
+        static final String TYPE_SCHEM = "TYPE_SCHEM"; //$NON-NLS-1$
+        // name of the column containing name of type name column.
+        static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+        //  name of the column containing super catalog or Virtual database name.
+        static final String SUPERTYPE_CAT = "SUPERTYPE_CAT"; //$NON-NLS-1$
+        // name of the column containing super schema or Virtual database version.
+        static final String SUPERTYPE_SCHEM = "SUPERTYPE_SCHEM"; //$NON-NLS-1$
+        // name of the column containing name of super type name column.
+        static final String SUPERTYPE_NAME = "SUPERTYPE_NAME"; //$NON-NLS-1$
+
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,576 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+/**
+ * <p> This class provides constants indicating positions of columns in the
+ * <code>ResultSets</code> returned by methods on <code>MMDatabaseMetaData</code>
+ * object. The inner classes represent the methods while attributes represent the
+ * column positions. The name of the constant explains the column content.</p>
+ * <p> The constants in the inner classes could include column positions for columns
+ * that are hardcoded, columns positions of some columns on server's
+ * <code>Results</code> object.</p>
+ * <p> Each of the inner classes have a constant <code>MAX_COLUMNS</code> that
+ * represents the number of columns to be read from the server's <code>Results</code>
+ * object.</p>
+ * <p> All the column positions are one based. </code>
+ */
+
+interface JDBCColumnPositions {
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface SCHEMAS {
+        /** Number of columns to be read from results returned getElements method. */
+        static final int MAX_COLUMNS = 2;
+        static final int TABLE_CATALOG = 2;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface CATALOGS {
+
+        /** Number of columns to be read from results returned getElements method. */
+        static final int MAX_COLUMNS = 1;
+    }
+
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface COLUMNS {
+
+        /** Number of columns to be read from results returned getElements method. */
+        static final int MAX_COLUMNS = 23;
+
+        /** Position of column that contains catalog name in which the table for the column is present. */
+        static final int TABLE_CAT = 1;
+
+        static final int TABLE_SCHEM = 2;
+        
+        static final int TABLE_NAME = 3;
+        
+        static final int COLUMN_NAME = 4; 
+        
+        /** Position of column that contains SQL type from java.sql.Types for column's data type. */
+        static final int DATA_TYPE = 5;
+
+        /** Position of column that contains local type name used by the data source. */
+        static final int TYPE_NAME = 6;
+
+        static final int COLUMN_SIZE = 7;
+        
+        /** Position of column that is not used will contain nulls */
+        static final int BUFFER_LENGTH = 8;
+
+        static final int DECIMAL_DIGITS = 9;
+        
+        static final int NUM_PREC_RADIX = 10;
+        
+        /** Position of column that has an int value indicating nullablity */
+        static final int NULLABLE = 11;
+
+        /** Position of column containing explanatory notes. */
+        static final int REMARKS = 12;
+
+        static final int COLUMN_DEF = 13;
+        
+        /** Position of column that not used will contain nulls */
+        static final int SQL_DATA_TYPE = 14;
+
+        /** Position of column that not used will contain nulls */
+        static final int SQL_DATETIME_SUB = 15;
+
+        static final int CHAR_OCTET_LENGTH = 16;
+        
+        static final int ORDINAL_POSITION = 17;
+        
+        /** Position of column that has an String value indicating nullablity */
+        static final int IS_NULLABLE = 18;
+        
+        static final int SCOPE_CATALOG = 19;
+        
+        static final int SCOPE_SCHEMA = 20;
+        
+        static final int SCOPE_TABLE = 21;
+        
+        static final int SOURCE_DATA_TYPE = 22;
+        
+        static final int IS_AUTOINCREMENT = 23;
+
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface TABLES {
+
+        /** Number of columns to be read from results returned getTables method. */
+        static final int MAX_COLUMNS = 11;
+        
+        /** Position of column that contains catalog name in which the table is present. */
+        static final int TABLE_CAT = 1;    
+        static final int TYPE_CAT = 6;
+        static final int TYPE_SCHEM = 7;
+        static final int TYPE_NAME = 8;
+        static final int SELF_REFERENCING_COL_NAME = 9;
+        static final int REF_GENERATION = 10;
+        static final int ISPHYSICAL = 11;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface TYPE_INFO {
+
+        /** Number of columns to be read from results returned getElements method. */
+        static final int MAX_COLUMNS = 18;
+
+        /** Position of column that contains local type name used by the data source. */
+        static final int TYPE_NAME = 1;
+
+        /** Position of column that contains SQL type from java.sql.Types for column's data type. */
+        static final int DATA_TYPE = 2;
+
+        static final int PRECISION = 3;
+        /** Position of column that contains prefix used to quote a literal. */
+        static final int LITERAL_PREFIX = 4;
+
+        /** Position of column that contains suffix used to quote a literal. */
+        static final int LITERAL_SUFFIX = 5;
+
+        /** Position of column that contains params used in creating the type. */
+        static final int CREATE_PARAMS = 6;
+
+        /** Position of column that contains the nullable value. */
+        static final int NULLABLE = 7;
+
+        static final int CASE_SENSITIVE = 8;
+        
+        /** Position of column that contains the searchable value. */
+        static final int SEARCHABLE = 9;
+        
+        /** Position of column that contains the unsigned value. */
+        static final int UNSIGNED_ATTRIBUTE = 10;
+
+        static final int FIXED_PREC_SCALE = 11;
+        
+        static final int AUTO_INCREMENT = 12;
+        
+        /** Position of column that contains local type name used by the data source. */
+        static final int LOCAL_TYPE_NAME = 13;
+
+        /** Position of column that contains the min scale value. */
+        static final int MINIMUM_SCALE = 14;
+
+        /** Position of column that contains the max scale value. */
+        static final int MAXIMUM_SCALE = 15;
+
+        /** Position of column that not used will contain nulls */
+        static final int SQL_DATA_TYPE = 16;
+
+        /** Position of column that not used will contain nulls */
+        static final int SQL_DATETIME_SUB = 17;
+        
+        static final int NUM_PREC_RADIX = 18;
+
+        /** Position of column in server's results containing name of the datatype.*/
+        static final int NAME = 19;
+        
+        /** Position of column in server's results containing isSigned value.*/
+        static final int IS_SIGNED = 20;
+
+        /** Position of column in server's results containing nullType name.*/
+        static final int NULL_TYPE_NAME = 21;
+
+        /** Position of column in server's results containing search type name.*/
+        static final int SEARCH_TYPE_NAME = 22;
+    }
+    
+    /**
+     * This class contains constants representing column positions on ResultSet
+     * returned by getUDTS method on DatabaseMetaData. These constant values
+     * are be used to hardcode the column values used in constructin the ResultSet obj.
+     */
+    interface UDTS {
+
+        /** Number of columns to be read from results returned getUserDefinedTypes method. */
+       static final int MAX_COLUMNS = 7;
+
+        // name of the column containing table or Groups name in which UDTS are present.
+       static final int TABLE_NAME = 3;
+
+        // name of the column containing catalog or Virtual database name.
+       static final int TYPE_CAT = 1;
+
+        // name of the column containing schema or Virtual database version.
+       static final int TYPE_SCHEM = 2;
+
+        // name of the column containing name of type name column.
+       static final int TYPE_NAME = 9;
+
+        // name of the column containing class name column.
+       static final int CLASS_NAME = 4;
+
+        // name of the column containing name of sql datatype code column
+       static final int DATA_TYPE = 5;
+
+        // name of the column containing comments column
+       static final int REMARKS = 6;
+       
+       static final int BASE_TYPE = 7;
+        /** Position of column in server's results containing java class name.*/
+       static final int JAVA_CLASS = 8;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getIndexInfo method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from the query against System.KeyElements table.</p>
+     */
+    interface INDEX_INFO {
+
+        /** Number of columns to be read from results returned by server results. */
+        static final int MAX_COLUMNS = 13;
+        
+        /** Position of column that contains catalog name of the table. */
+        static final int TABLE_CAT = 1;
+        
+        static final int TABLE_SCHEM = 2;
+        
+        static final int TABLE_NAME = 3;
+        
+        /** Position of column that contains non uniqueness of the index. */
+        static final int NON_UNIQUE = 4;
+        
+        /** Position of column that contains qualifier for the index. */
+        static final int INDEX_QUALIFIER = 5;
+        
+        static final int INDEX_NAME = 6;
+        
+        /** Position of column that contains type of index. */
+        static final int TYPE = 7;
+        
+        static final int ORDINAL_POSITION = 8;
+        
+        static final int COLUMN_NAME = 9;
+        
+        /** Position of column that contains desc if index is ascending or descending. */
+        static final int ASC_OR_DESC = 10;
+        
+        /** Position of column that contains cardinality of the index. */
+        static final int CARDINALITY = 11;
+        
+        /** Position of column that contains pages oocupied by table. */
+        static final int PAGES = 12;
+        
+        /** Position of column that contains any filter condition. */
+        static final int FILTER_CONDITION = 13;     
+
+    }    
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface PRIMARY_KEYS {
+
+        /** Number of columns to be read from results returned by getPrimaryKeys. */
+        static final int MAX_COLUMNS = 6;
+        
+        /** Position of column that contains catalog name of the primaryTable. */
+        static final int TABLE_CAT = 1;    
+        static final int TABLE_SCHEM = 2;
+        static final int TABLE_NAME = 3;
+        static final int COLUMN_NAME = 4;
+        static final int KEY_SEQ = 5; 
+        static final int PK_NAME = 6;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getCrossReferences method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getCrossReferences method on server's <code>Metadata object</code>.
+     */
+    interface REFERENCE_KEYS {
+
+        /** Number of columns to be read from results returned any of the 3 methods. */
+        static final int MAX_COLUMNS = 14;
+
+        /** Position of column that contains catalog name of the primaryTable. */
+        static final int PKTABLE_CAT = 1;
+        
+        /** Position of column that contains scheam name of the primaryTable. */
+        static final int PKTABLE_SCHEM = 2;   
+        
+        static final int PKTABLE_NAME = 3;
+        
+        static final int PKCOLUMN_NAME = 4;     
+
+        /** Position of column that contains catalog name of the foreignTable. */
+        static final int FKTABLE_CAT = 5;
+        
+        /** Position of column that contains schema name of the foreignTable. */
+        static final int FKTABLE_SCHEM = 6;        
+
+        static final int FKTABLE_NAME = 7;
+        
+        static final int FKCOLUMN_NAME = 8;   
+        
+        static final int KEY_SEQ = 9;
+        
+        /** Position of column that determines how forein key changes if PK is updated. */
+        static final int UPDATE_RULE = 10;                                                     
+                
+        /** Position of column that determines how forein key changes if PK is deleted. */
+        static final int DELETE_RULE = 11;
+
+        static final int FK_NAME = 12;
+        
+        static final int PK_NAME = 13;
+        
+        /** Position of column that determines if forein key constraints can be deffered until commit. */
+        static final int DEFERRABILITY = 14;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getProcedures method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface PROCEDURES {
+
+        /** Number of columns to be read from results returned getCrossReferences method. */
+        static final int MAX_COLUMNS = 9;
+
+        /** Position of column that contains catalog name of the procedure. */
+        static final int PROCEDURE_CAT = 1;
+        static final int PROCEDURE_SCHEM = 2;
+        static final int PROCEDURE_NAME = 3;
+        
+        /** Position of column the is reserved for future use. */
+        static final int RESERVED_1 = 4;
+
+        /** Position of column the is reserved for future use. */
+        static final int RESERVED_2 = 5;
+
+        /** Position of column the is reserved for future use. */
+        static final int RESERVED_3 = 6;
+
+        static final int REMARKS = 7;
+        
+        /** Position of column Procedure type. */
+        static final int PROCEDURE_TYPE = 8;
+        
+        static final int SPECIFIC_NAME = 9;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     * <code>JAVA_CLASS</code> is the column position for element data type on
+     * server's Results object.
+     */
+    interface PROCEDURE_COLUMNS {
+
+        /** Number of columns to be read from results returned getProcedureColumns method. */
+        static final int MAX_COLUMNS = 20;
+        
+        /** Position of column that contains catalog name of the procedure. */
+        static final int PROCEDURE_CAT = 1;     
+
+        static final int PROCEDURE_SCHEM = 2;
+        static final int PROCEDURE_NAME = 3; 
+        static final int COLUMN_NAME = 4;
+        
+        /** Position of the column containing column or element type. */
+        static final int COLUMN_TYPE = 5;
+
+        /** Position of column that contains SQL type from java.sql.Types for column's data type. */
+        static final int DATA_TYPE = 6;
+
+        /** Position of column that contains local type name used by the data source. */
+        static final int TYPE_NAME = 7;
+
+        static final int PRECISION = 8;
+        static final int LENGTH = 9;
+        static final int SCALE = 10;
+        static final int RADIX = 11;
+               
+        /** Position of column that contains the nullable value. */
+        static final int NULLABLE = 12;
+
+        /** Position of column that contains comments. */
+        static final int REMARKS = 13;
+        static final int COLUMN_DEF = 14;
+        
+        static final int SQL_DATA_TYPE = 15;
+        static final int SQL_DATETIME_SUB = 16;
+        static final int CHAR_OCTET_LENGTH = 17;
+        
+        static final int ORDINAL_POSITION = 18;
+        
+        static final int IS_NULLABLE = 19;
+        
+        static final int SPECIFIC_NAME = 20;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class also has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     */
+    interface TABLE_PRIVILEGES {
+
+        /** Number of columns to be read from results returned getGroupEntitlements method. */
+        static final int MAX_COLUMNS = 6;
+        
+        /** Position of VirtualDatabaseName column in server's results object returned by
+         getGroupEntitlements method in User API */
+        static final int VIRTUAL_DATABASE_NAME = 0;
+        
+        /** Position of VirtualDatabaseVersion column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int VIRTUAL_DATABASE_VERSION = 1;      
+        
+        /** Position of GroupName column in server's results object returned by
+         getGroupEntitlements method in User API */
+        static final int GROUP_NAME = 2;
+        
+        /** Position of Grantor column in server's results object returned by
+         getGroupEntitlements method in User API */
+        static final int GRANTOR = 3;
+        
+        /** Position of Grantee column in server's results object returned by
+         getGroupEntitlements method in User API */
+        static final int GRANTEE = 4;
+
+        /** Position of Permission column in server's results object returned by
+         getGroupEntitlements method in User API */
+        static final int PERMISSION = 5;
+        
+        /** Position of the column containing catalog name info. */
+        static final int TABLE_CAT = 0;     
+
+        /** Position of the column containing privilage grantable info. */
+        static final int IS_GRANTABLE = 6;
+    }
+
+    /**
+     * <p>This class contains constants representing column positions on ResultSet
+     * returned by getColumns method on DatabaseMetaData. The class also has constants
+     * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+     * <code>MAX_COLUMNS</code> is the number of columns to be read from server's
+     * results from getElements method on <code>Metadata object</code>.
+     */
+    interface COLUMN_PRIVILEGES {
+
+        /** Number of columns to be read from results returned getElementEntitlements method. */
+        static final int MAX_COLUMNS = 7;
+        
+        /** Position of VirtualDatabaseName column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int VIRTUAL_DATABASE_NAME = 0;
+        
+        /** Position of VirtualDatabaseVersion column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int VIRTUAL_DATABASE_VERSION = 1;
+        
+        /** Position of GroupName column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int GROUP_NAME = 2;
+        
+        /** Position of ElementName column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int ELEMENT_NAME = 3;
+        
+        /** Position of Grantor column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int GRANTOR = 4;
+        
+        /** Position of Grantee column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int GRANTEE = 5;
+
+        /** Position of Permission column in server's results object returned by
+         getElementEntitlements method in User API */
+        static final int PERMISSION = 6;
+
+        /** Position of the column containing catalog name info. */
+        static final int TABLE_CAT = 0;
+
+        /** Position of the column containing privilage grantable info. */
+        static final int IS_GRANTABLE = 7;
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCPlugin.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.util.ResourceBundle;
+import com.metamatrix.core.BundleUtil;
+
+/**
+ * JDBCPlugin
+ * <p>Used here in <code>jdbc</code> to have access to the new
+ * logging framework.</p>
+ */
+public class JDBCPlugin { // extends Plugin {
+
+    public static final String PLUGIN_ID = "org.teiid.jdbc" ; //$NON-NLS-1$
+
+	public static final BundleUtil Util = new BundleUtil(PLUGIN_ID,
+	                                                     PLUGIN_ID + ".i18n", ResourceBundle.getBundle(PLUGIN_ID + ".i18n")); //$NON-NLS-1$ //$NON-NLS-2$
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCURL.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,324 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.teiid.net.TeiidURL;
+
+
+
+
+
+
+/** 
+ * @since 4.3
+ */
+public class JDBCURL {
+    private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
+    public static final String JDBC_PROTOCOL = "jdbc:teiid:"; //$NON-NLS-1$
+    private static final String OLD_JDBC_PROTOCOL = "jdbc:metamatrix:"; //$NON-NLS-1$
+    
+    public static final String[] KNOWN_PROPERTIES = {
+        BaseDataSource.APP_NAME,
+        BaseDataSource.VDB_NAME,
+        BaseDataSource.VERSION,
+        BaseDataSource.VDB_VERSION,
+        BaseDataSource.USER_NAME,
+        BaseDataSource.PASSWORD,
+        ExecutionProperties.PROP_TXN_AUTO_WRAP,
+        ExecutionProperties.PROP_PARTIAL_RESULTS_MODE,
+        ExecutionProperties.RESULT_SET_CACHE_MODE,
+        ExecutionProperties.ANSI_QUOTED_IDENTIFIERS,
+        ExecutionProperties.PROP_SQL_OPTIONS,
+        ExecutionProperties.PROP_FETCH_SIZE,
+        ExecutionProperties.PROP_XML_FORMAT,
+        ExecutionProperties.PROP_XML_VALIDATION,
+        ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS,
+        TeiidURL.CONNECTION.AUTO_FAILOVER,
+        TeiidURL.CONNECTION.DISCOVERY_STRATEGY
+    };
+    
+    private String vdbName;
+    private String connectionURL;
+    private Properties properties = new Properties();
+    
+    private String urlString;
+    
+    public JDBCURL(String jdbcURL) {
+        parseURL(jdbcURL);
+    }
+    
+    public JDBCURL(String vdbName, String connectionURL, Properties props) {
+        if (vdbName == null || vdbName.trim().length() == 0) {
+            throw new IllegalArgumentException();
+        }
+        this.vdbName = vdbName;
+        this.connectionURL = connectionURL;
+        if (props != null) {
+            normalizeProperties(props, this.properties);
+        }
+    }
+    
+    public String getVDBName() {
+        return vdbName;
+    }
+    
+    public String getConnectionURL() {
+        return connectionURL;
+    }
+    
+    public Properties getProperties() {
+        // Make a copy of the properties object, including any non-string values that may be contained in the map.
+        Properties newProps = new Properties();
+        newProps.putAll(this.properties);
+        return newProps;
+    }
+    
+    private void parseURL(String jdbcURL) {
+        if (jdbcURL == null) {
+            throw new IllegalArgumentException();
+        }
+        // Trim extra spaces
+        jdbcURL = jdbcURL.trim();
+        if (jdbcURL.length() == 0) {
+            throw new IllegalArgumentException();
+        }
+        int delimiter = jdbcURL.indexOf('@');
+        if (delimiter == -1) {
+            // this is for default connection protocol in embedded driver.
+            // then go by first semi colon
+            int fsc = jdbcURL.indexOf(';');
+            if (fsc == -1) {
+                parseJDBCProtocol(jdbcURL);
+            }
+            else {
+                parseJDBCProtocol(jdbcURL.substring(0, fsc));
+                parseConnectionProperties(jdbcURL.substring(fsc+1), this.properties);
+            }
+        }
+        else {
+            String[] urlParts = jdbcURL.split("@", 2); //$NON-NLS-1$
+            if (urlParts.length != 2) {
+                throw new IllegalArgumentException();
+            }
+            parseJDBCProtocol(urlParts[0]);
+            parseConnectionPart(urlParts[1]);
+        }
+    }
+
+    private void parseJDBCProtocol(String protocol) {
+        if (protocol.startsWith(JDBC_PROTOCOL)) {
+	        if (protocol.length() == JDBC_PROTOCOL.length()) {
+	            throw new IllegalArgumentException();
+	        }
+	        vdbName = protocol.substring(JDBC_PROTOCOL.length());
+        }
+        else if (protocol.startsWith(OLD_JDBC_PROTOCOL)) {
+	        if (protocol.length() == OLD_JDBC_PROTOCOL.length()) {
+	            throw new IllegalArgumentException();
+	        }
+	        vdbName = protocol.substring(OLD_JDBC_PROTOCOL.length());
+        }
+        else {
+        	throw new IllegalArgumentException();
+        }
+        
+    }
+    
+    private void parseConnectionPart(String connectionInfo) {
+        String[] connectionParts = connectionInfo.split(";"); //$NON-NLS-1$
+        if (connectionParts.length == 0 || connectionParts[0].trim().length() == 0) {
+            throw new IllegalArgumentException();
+        }
+        connectionURL = connectionParts[0].trim();
+        if (connectionParts.length > 1) {
+            // The rest should be connection params
+            for (int i = 1; i < connectionParts.length; i++) {
+                parseConnectionProperty(connectionParts[i], this.properties);
+            }
+        }
+    }
+    
+    public static void parseConnectionProperties(String connectionInfo, Properties p) {
+        String[] connectionParts = connectionInfo.split(";"); //$NON-NLS-1$
+        if (connectionParts.length != 0) {
+            // The rest should be connection params
+            for (int i = 0; i < connectionParts.length; i++) {
+                parseConnectionProperty(connectionParts[i], p);
+            }
+        }
+    }
+    
+    static void parseConnectionProperty(String connectionProperty, Properties p) {
+        if (connectionProperty.length() == 0) {
+            // Be tolerant of double-semicolons and dangling semicolons
+            return;
+        } else if(connectionProperty.length() < 3) {
+            // key=value must have at least 3 characters
+            throw new IllegalArgumentException();
+        }
+        int firstEquals = connectionProperty.indexOf('=');
+        if(firstEquals < 1) {
+            throw new IllegalArgumentException();
+        } 
+        String key = connectionProperty.substring(0, firstEquals).trim();
+        String value = connectionProperty.substring(firstEquals+1).trim();        
+        if(value.indexOf('=') >= 0) {
+            throw new IllegalArgumentException();
+        }        
+        addNormalizedProperty(key, getValidValue(value), p);
+    }
+    
+    public String getJDBCURL() {
+        if (urlString == null) {
+            StringBuffer buf = new StringBuffer(JDBC_PROTOCOL)
+                .append(vdbName);
+            	if (this.connectionURL != null) {
+            		buf.append('@').append(connectionURL);
+            	}
+            for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
+                Map.Entry entry = (Map.Entry)i.next();
+                if (entry.getValue() instanceof String) {
+                    // get only the string properties, because a non-string property could not have been set on the url.
+                    buf.append(';')
+                       .append(entry.getKey())
+                       .append('=')
+                       .append(entry.getValue());
+                }
+            }
+            urlString = buf.toString();
+        }
+        return urlString;
+    }
+    
+    public String getProperty(String key) {
+        return properties.getProperty(key);
+    }
+    
+    public String getUserName() {
+        return properties.getProperty(BaseDataSource.USER_NAME);
+    }
+    
+    public String getPassword() {
+        return properties.getProperty(BaseDataSource.PASSWORD);
+    }
+    
+    public String getVDBVersion() {
+        if (properties.contains(BaseDataSource.VDB_VERSION)) {
+        	return properties.getProperty(BaseDataSource.VDB_VERSION);
+        }
+        return properties.getProperty(BaseDataSource.VERSION);
+    }
+        
+    public String getTransactionAutowrapMode() {
+        return properties.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP);
+    }
+    
+    public String getPartialResultsMode() {
+        return properties.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE);
+    }
+    
+    public String getResultSetCacheMode() {
+        return properties.getProperty(ExecutionProperties.RESULT_SET_CACHE_MODE);
+    }
+    
+    public String getAnsiQuotedIdentifiers() {
+        return properties.getProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS);
+    }
+    
+    public String getSQLOptions() {
+        return properties.getProperty(ExecutionProperties.PROP_SQL_OPTIONS);
+    }
+    
+    public String getFetchSize() {
+        return properties.getProperty(ExecutionProperties.PROP_FETCH_SIZE);
+    }
+    
+    public String getXMLFormat() {
+        return properties.getProperty(ExecutionProperties.PROP_XML_FORMAT);
+    }
+    
+    public String getXMLValidation() {
+        return properties.getProperty(ExecutionProperties.PROP_XML_VALIDATION);
+    }
+    
+    public String getTransparentFailover() {
+        return properties.getProperty(TeiidURL.CONNECTION.AUTO_FAILOVER);
+    }
+    
+    public String getDisableLocalTransactions() {
+        return properties.getProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS);
+    }
+    
+    public String toString() {
+        return getJDBCURL();
+    }
+        
+    private static void normalizeProperties(Properties source, Properties target) {
+        for (Enumeration e = source.propertyNames(); e.hasMoreElements();) {
+            String key = (String)e.nextElement();
+            addNormalizedProperty(key, source.get(key), target);
+        }
+    }    
+    
+    private static void addNormalizedProperty(String key, Object value, Properties target) {
+        String validKey = getValidKey(key);
+         
+        // now add the normalized key and value into the properties object.
+        target.put(validKey, value);
+    }
+
+    private static String getValidKey(String key) {
+        // figure out the valid key based on its case
+        for (int i = 0; i < KNOWN_PROPERTIES.length; i++) {
+            if (key.equalsIgnoreCase(KNOWN_PROPERTIES[i])) {
+                return KNOWN_PROPERTIES[i];
+            }
+        }
+        return key;
+    }
+    
+    private static Object getValidValue(Object value) {
+        if (value instanceof String) {
+            try {
+                // Decode the value of the property if incase they were encoded.
+                return URLDecoder.decode((String)value, UTF_8);
+            } catch (UnsupportedEncodingException e) {
+                // use the original value
+            }            
+        }
+        return value;
+    }
+    
+    public static Properties normalizeProperties(Properties props) {
+        normalizeProperties(props, props);
+        return props;
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/MetadataProvider.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.Map;
+
+
+/**
+ */
+public class MetadataProvider {
+
+    // Map of detail maps -- <columnIndex, Map<propertyName, metadataObject>>
+	protected Map[] metadata;
+
+    public MetadataProvider(Map[] metadata) {
+    	this.metadata = metadata;
+    }
+    
+    public Object getValue(int columnIndex, Integer metadataPropertyKey) throws SQLException {
+        if(columnIndex < 0 || columnIndex >= metadata.length) {
+            throw new SQLException(JDBCPlugin.Util.getString("StaticMetadataProvider.Invalid_column", columnIndex)); //$NON-NLS-1$
+        }
+        
+        Map column = this.metadata[columnIndex];
+        return column.get(metadataPropertyKey);
+    }
+
+    public int getColumnCount() throws SQLException {
+        return metadata.length;
+    }
+    
+    public String getStringValue(int columnIndex, Integer metadataPropertyKey) throws SQLException {
+        return (String) getValue(columnIndex, metadataPropertyKey);
+    }
+
+    public int getIntValue(int columnIndex, Integer metadataPropertyKey) throws SQLException {
+        return ((Integer) getValue(columnIndex, metadataPropertyKey)).intValue();
+    }
+
+    public boolean getBooleanValue(int columnIndex, Integer metadataPropertyKey) throws SQLException {
+        return ((Boolean) getValue(columnIndex, metadataPropertyKey)).booleanValue();
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+
+/**
+ * Note: this is currently only accurate for {@link PreparedStatement}s.
+ * Only the basic type information will be accurate for {@link CallableStatement}s. 
+ */
+public class ParameterMetaDataImpl extends WrapperImpl implements ParameterMetaData {
+	
+	private ResultSetMetaDataImpl metadata;
+	
+	public ParameterMetaDataImpl(ResultSetMetaDataImpl metadata) {
+		this.metadata = metadata;
+	}
+
+	@Override
+	public String getParameterClassName(int param) throws SQLException {
+		return MMJDBCSQLTypeInfo.getJavaClassName(getParameterType(param));
+	}
+
+	@Override
+	public int getParameterCount() throws SQLException {
+		return metadata.getColumnCount();
+	}
+
+	@Override
+	public int getParameterMode(int param) throws SQLException {
+		return parameterModeUnknown;
+	}
+
+	@Override
+	public int getParameterType(int param) throws SQLException {
+		return metadata.getColumnType(param);
+	}
+
+	@Override
+	public String getParameterTypeName(int param) throws SQLException {
+		return metadata.getColumnTypeName(param);
+	}
+
+	@Override
+	public int getPrecision(int param) throws SQLException {
+		return metadata.getPrecision(param);
+	}
+
+	@Override
+	public int getScale(int param) throws SQLException {
+		return metadata.getScale(param);
+	}
+
+	@Override
+	public int isNullable(int param) throws SQLException {
+		return metadata.isNullable(param);
+	}
+
+	@Override
+	public boolean isSigned(int param) throws SQLException {
+		return metadata.isSigned(param);
+	}
+
+}


Property changes on: trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/PartialResultsWarning.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * This warning class is sent when using partial results mode if one or more
+ * sources fails.  In this case, results will be returned (with 0 rows sent from
+ * failing source).  This warning can be obtained from the ResultSet to determine
+ * which sources failed and provided 0 rows and why they failed.  
+ */
+public class PartialResultsWarning extends SQLWarning {
+
+	private static final long serialVersionUID = 5301215068719177369L;
+	private Map failures; 
+
+    /**
+     * Construct partial results warning.
+     * @param reason Reason for the exception
+     * @param SQLstate SQL state code
+     * @param vendorCode Vendor code
+     */
+    public PartialResultsWarning(String reason, String SQLstate, int vendorCode) {
+        super(reason, SQLstate, vendorCode);
+    }
+
+    /**
+     * Construct partial results warning.
+     * @param reason Reason for the exception
+     * @param SQLstate SQL state code
+     */
+    public PartialResultsWarning(String reason, String SQLstate) {
+        super(reason, SQLstate);
+    }
+
+    /**
+     * Construct partial results warning.
+     * @param reason Reason for the exception
+     */
+    public PartialResultsWarning(String reason) {
+        super(reason);
+    }
+
+    /**
+     * Construct partial results warning.
+     */
+    public PartialResultsWarning() {
+        super();
+    }
+    
+    /**
+     * Add a connector failure to the warning
+     * @param name Connector name
+     * @param exception Connector exception
+     */
+    public void addConnectorFailure(String name, SQLException exception) {
+        if(this.failures == null) {
+            this.failures = new HashMap();
+        }
+        this.failures.put(name, exception);
+    }
+    
+    /**
+     * Obtain list of connectors that failed.  
+     * @return List of connectors that failed - List contains String names
+     */
+    public Collection getFailedConnectors() {
+        if(this.failures != null) {
+            return new HashSet(this.failures.keySet());
+        }
+        return Collections.EMPTY_SET;
+    }
+    
+    /**
+     * Obtain failure for a particular connector.
+     * @param name Connector name
+     * @return Exception that occurred for this connector or null if
+     * the exception was unknown
+     */
+    public SQLException getConnectorException(String connectorName) {
+        if(this.failures != null) {
+            return (SQLException) this.failures.get(connectorName);    
+        }
+        return null;
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,787 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.TreeMap;
+
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+
+import org.teiid.client.RequestMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.RequestMessage.StatementType;
+import org.teiid.client.metadata.MetadataResult;
+
+
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.common.util.TimestampWithTimezone;
+import com.metamatrix.core.util.ArgCheck;
+import com.metamatrix.core.util.ObjectConverterUtil;
+
+/**
+ * <p> Instances of PreparedStatement contain a SQL statement that has already been
+ * compiled.  The SQL statement contained in a PreparedStatement object may have
+ * one or more IN parameters. An IN parameter is a parameter whose value is not
+ * specified when a SQL statement is created. Instead the statement has a placeholder
+ * for each IN parameter.</p>
+ * <p> The MMPreparedStatement object wraps the server's PreparedStatement object.
+ * The methods in this class are used to set the IN parameters on a server's
+ * preparedstatement object.</p>
+ */
+
+public class PreparedStatementImpl extends StatementImpl implements PreparedStatement {
+    // sql, which this prepared statement is operating on
+    protected String prepareSql;
+
+    //map that holds parameter index to values for prepared statements
+    private Map<Integer, Object> parameterMap;
+    
+    //a list of map that holds parameter index to values for prepared statements
+    protected List<List<Object>> batchParameterList;
+
+    // metadata
+	private MetadataResult metadataResults;
+    private ResultSetMetaData metadata;
+    private ParameterMetaData parameterMetaData;
+    
+    private Calendar serverCalendar;
+
+    /**
+     * Factory Constructor 
+     * @param connection
+     * @param sql
+     * @param resultSetType
+     * @param resultSetConcurrency
+     */
+    static PreparedStatementImpl newInstance(ConnectionImpl connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return new PreparedStatementImpl(connection, sql, resultSetType, resultSetConcurrency);        
+    }
+    
+    /**
+     * <p>MMPreparedStatement constructor.
+     * @param Driver's connection object.
+     * @param String object representing the prepared statement
+     */
+    PreparedStatementImpl(ConnectionImpl connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        super(connection, resultSetType, resultSetConcurrency);
+
+        // this sql is for callable statement, don't check any more
+        ArgCheck.isNotNull(sql, JDBCPlugin.Util.getString("MMPreparedStatement.Err_prep_sql")); //$NON-NLS-1$
+        this.prepareSql = sql;
+
+        TimeZone timezone = connection.getServerConnection().getLogonResult().getTimeZone();
+
+        if (timezone != null && !timezone.hasSameRules(getDefaultCalendar().getTimeZone())) {
+        	this.serverCalendar = Calendar.getInstance(timezone);
+        }        
+    }
+
+    /**
+     * <p>Adds a set of parameters to this PreparedStatement object's list of commands
+     * to be sent to the database for execution as a batch.
+     * @throws SQLException if there is an error
+     */
+    public void addBatch() throws SQLException {
+        checkStatement();
+    	if(batchParameterList == null){
+    		batchParameterList = new ArrayList<List<Object>>();
+		}
+    	batchParameterList.add(getParameterValues());
+		clearParameters();
+    }
+
+    /**
+     * Makes the set of commands in the current batch empty.
+     *
+     * @throws SQLException if a database access error occurs or the
+     * driver does not support batch statements
+     */
+    public void clearBatch() throws SQLException {
+    	if (batchParameterList != null ) {
+    		batchParameterList.clear();
+    	}
+    }
+
+    /**
+     * <p>Clears the values set for the PreparedStatement object's IN parameters and
+     * releases the resources used by those values. In general, parameter values
+     * remain in force for repeated use of statement.
+     * @throws SQLException if there is an error while clearing params
+     */
+    public void clearParameters() throws SQLException {
+        checkStatement();
+        //clear the parameters list on servers prepared statement object
+        if(parameterMap != null){
+            parameterMap.clear();
+        }
+    }
+    
+    @Override
+    public boolean execute(String sql) throws SQLException {
+    	String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported"); //$NON-NLS-1$
+        throw new TeiidSQLException(msg);
+    }
+    
+    @Override
+    public ResultSet executeQuery(String sql) throws SQLException {
+    	String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported"); //$NON-NLS-1$
+        throw new TeiidSQLException(msg);
+    }
+    
+    @Override
+    public int executeUpdate(String sql) throws SQLException {
+    	String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported"); //$NON-NLS-1$
+        throw new TeiidSQLException(msg);
+    }
+    
+    @Override
+    public void addBatch(String sql) throws SQLException {
+    	String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported"); //$NON-NLS-1$
+        throw new TeiidSQLException(msg);
+    }
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public boolean execute() throws SQLException {
+        executeSql(new String[] {this.prepareSql}, false, ResultsMode.EITHER);
+        return hasResultSet();
+    }
+    
+    @Override
+    public int[] executeBatch() throws SQLException {
+    	if (batchParameterList == null || batchParameterList.isEmpty()) {
+   	     	return new int[0];
+    	}
+	   	try{
+	   		executeSql(new String[] {this.prepareSql}, true, ResultsMode.UPDATECOUNT);
+	   	}finally{
+	   		batchParameterList.clear();
+	   	}
+	   	return this.updateCounts;
+    }
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public ResultSet executeQuery() throws SQLException {
+        executeSql(new String[] {this.prepareSql}, false, ResultsMode.RESULTSET);
+        return resultSet;
+    }
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public int executeUpdate() throws SQLException {
+        executeSql(new String[] {this.prepareSql}, false, ResultsMode.UPDATECOUNT);
+        return this.updateCounts[0];
+    }
+    
+    @Override
+    protected RequestMessage createRequestMessage(String[] commands,
+    		boolean isBatchedCommand, ResultsMode resultsMode) {
+    	RequestMessage message = super.createRequestMessage(commands, false, resultsMode);
+    	message.setStatementType(StatementType.PREPARED);
+    	message.setParameterValues(isBatchedCommand?getParameterValuesList(): getParameterValues());
+    	message.setBatchedUpdate(isBatchedCommand);
+    	return message;
+    }
+
+    /**
+     * <p>Retreives a ResultSetMetaData object with information about the numbers,
+     * types, and properties of columns in the ResultSet object that will be returned
+     * when this preparedstatement object is executed.
+     * @return ResultSetMetaData object
+     * @throws SQLException, currently there is no means of getting results
+     * metadata before getting results.
+     */
+    public ResultSetMetaData getMetaData() throws SQLException {
+
+        // check if the statement is open
+        checkStatement();
+
+        if(metadata == null) {
+        	if (updateCounts != null) {
+        		return null;
+        	} else if(resultSet != null) {
+                metadata = resultSet.getMetaData();
+            } else {
+				if (getMetadataResults().getColumnMetadata() == null) {
+					return null;
+				}
+                MetadataProvider provider = new MetadataProvider(getMetadataResults().getColumnMetadata());
+                metadata = new ResultSetMetaDataImpl(provider);
+            }
+        }
+
+        return metadata;
+    }
+
+	private MetadataResult getMetadataResults() throws TeiidSQLException {
+		if (metadataResults == null) {
+			try {
+				metadataResults = this.getDQP().getMetadata(this.currentRequestID, prepareSql, Boolean.valueOf(getExecutionProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS)).booleanValue());
+			} catch (MetaMatrixComponentException e) {
+				throw TeiidSQLException.create(e);
+			} catch (MetaMatrixProcessingException e) {
+				throw TeiidSQLException.create(e);
+			}
+		}
+		return metadataResults;
+	}
+
+    public void setAsciiStream (int parameterIndex, java.io.InputStream in, int length) throws SQLException {
+        //create a clob from the ascii stream
+    	try {
+			setObject(parameterIndex, new SerialClob(ObjectConverterUtil.convertToCharArray(in, length, "ASCII"))); //$NON-NLS-1$
+		} catch (IOException e) {
+			throw TeiidSQLException.create(e);
+		} 
+    }
+
+    /**
+     * <p>Sets the IN parameter at paramaterIndex to a BigDecimal object. The parameter
+     * type is set to NUMERIC
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param BigDecimal object to which the parameter value is to be set.
+     * @throws SQLException, should not occur
+     */
+    public void setBigDecimal (int parameterIndex, java.math.BigDecimal value) throws SQLException {
+        setObject(parameterIndex, value);
+    }
+
+    public void setBinaryStream(int parameterIndex, java.io.InputStream in, int length) throws SQLException {
+    	//create a blob from the ascii stream
+    	try {
+			setObject(parameterIndex, new SerialBlob(ObjectConverterUtil.convertToByteArray(in, length)));
+		} catch (IOException e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    /**
+     * <p>Sets the parameter in position parameterIndex to a Blob object.
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Blob object to which the parameter value is to be set.
+     * @throws SQLException if parameter type/datatype do not match
+     */
+    public void setBlob (int parameterIndex, Blob x) throws SQLException {
+        setObject(parameterIndex, x);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to b, a Java boolean value. The parameter
+     * type is set to BIT
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param boolean value to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setBoolean (int parameterIndex, boolean value) throws SQLException {
+        setObject(parameterIndex, new Boolean(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a Java byte value. The parameter
+     * type is set to TINYINT
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param byte value to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setByte(int parameterIndex, byte value) throws SQLException {
+        setObject(parameterIndex, new Byte(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x[], a Java array of bytes.
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param bytes array to which the parameter value is to be set.
+     */
+    public void setBytes(int parameterIndex, byte bytes[]) throws SQLException {
+    	//create a blob from the ascii stream
+    	setObject(parameterIndex, new SerialBlob(bytes));
+    }
+
+    public void setCharacterStream (int parameterIndex, java.io.Reader reader, int length) throws SQLException {
+    	//create a clob from the ascii stream
+    	try {
+			setObject(parameterIndex, new SerialClob(ObjectConverterUtil.convertToCharArray(reader, length)));
+		} catch (IOException e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    /**
+     * <p>Sets the parameter in position parameterIndex to a Clob object.
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Clob object to which the parameter value is to be set.
+     * @throws SQLException if parameter type/datatype do not match.
+     */
+    public void setClob (int parameterIndex, Clob x) throws SQLException {
+        setObject(parameterIndex, x);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a java.sql.Date object. The parameter
+     * type is set to DATE
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Date object to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setDate(int parameterIndex, java.sql.Date value) throws SQLException {
+        setDate(parameterIndex, value, null);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a java.sql.Date object. The parameter
+     * type is set to DATE
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Date object to which the parameter value is to be set.
+     * @param Calendar object to constrct date(useful to get include timezone info)
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setDate(int parameterIndex, java.sql.Date x ,java.util.Calendar cal) throws SQLException {
+
+        if (cal == null || x == null) {
+            setObject(parameterIndex, x);
+            return;
+        }
+                
+        // set the parameter on the stored procedure
+        setObject(parameterIndex, TimestampWithTimezone.createDate(x, cal.getTimeZone(), getDefaultCalendar()));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a double value. The parameter
+     * type is set to DOUBLE
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param double value to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setDouble(int parameterIndex, double value) throws SQLException {
+        setObject(parameterIndex, new Double(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to value, a float value. The parameter
+     * type is set to FLOAT
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param float value to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setFloat(int parameterIndex, float value) throws SQLException {
+        setObject(parameterIndex, new Float(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to value, a int value. The parameter
+     * type is set to INTEGER
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param int value to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setInt(int parameterIndex, int value) throws SQLException {
+        setObject(parameterIndex, new Integer(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a long value. The parameter
+     * type is set to BIGINT
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param long value to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setLong(int parameterIndex, long value) throws SQLException {
+        setObject(parameterIndex, new Long(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to a null value.
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param jdbc type of the parameter whose value is to be set to null
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setNull(int parameterIndex, int jdbcType) throws SQLException {
+        setObject(parameterIndex, null);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to a null value.
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param jdbc type of the parameter whose value is to be set to null
+     * @param fully qualifies typename of the parameter being set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setNull(int parameterIndex, int jdbcType, String typeName) throws SQLException {
+        setObject(parameterIndex, null);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to an object value
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param an object value to which the parameter value is to be set.
+     * @param int value giving the JDBC type to conver the object to
+     * @param int value giving the scale to be set if the type is DECIMAL or NUMERIC
+     * @throws SQLException, if there is an error setting the parameter value
+     */
+    public void setObject (int parameterIndex, Object value, int targetJdbcType, int scale) throws SQLException {
+
+       if(value == null) {
+            setObject(parameterIndex, null);
+            return;
+        }
+
+       if(targetJdbcType != Types.DECIMAL || targetJdbcType != Types.NUMERIC) {
+            setObject(parameterIndex, value, targetJdbcType);
+        // Decimal and NUMERIC types correspong to java.math.BigDecimal
+        } else {
+            // transform the object to a BigDecimal
+            BigDecimal bigDecimalObject = DataTypeTransformer.getBigDecimal(value);
+            // set scale on the BigDecimal
+            bigDecimalObject.setScale(scale);
+
+            setObject(parameterIndex, bigDecimalObject);
+        }
+    }
+    
+    public void setObject(int parameterIndex, Object value, int targetJdbcType) throws SQLException {
+
+        Object targetObject = null;
+
+       if(value == null) {
+            setObject(parameterIndex, null);
+            return;
+        }
+
+        // get the java class name for the given JDBC type
+        String javaClassName = MMJDBCSQLTypeInfo.getJavaClassName(targetJdbcType);
+        // transform the value to the target datatype
+        if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.STRING_CLASS)) {
+           targetObject = value.toString();
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.CHAR_CLASS)) {
+            targetObject = DataTypeTransformer.getCharacter(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.INTEGER_CLASS)) {
+            targetObject = DataTypeTransformer.getInteger(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BYTE_CLASS)) {
+            targetObject = DataTypeTransformer.getByte(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.SHORT_CLASS)) {
+            targetObject = DataTypeTransformer.getShort(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.LONG_CLASS)) {
+            targetObject = DataTypeTransformer.getLong(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.FLOAT_CLASS)) {
+            targetObject = DataTypeTransformer.getFloat(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.DOUBLE_CLASS)) {
+            targetObject = DataTypeTransformer.getDouble(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BOOLEAN_CLASS)) {
+            targetObject = DataTypeTransformer.getBoolean(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BIGDECIMAL_CLASS)) {
+            targetObject = DataTypeTransformer.getBigDecimal(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.TIMESTAMP_CLASS)) {
+            targetObject = DataTypeTransformer.getTimestamp(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.DATE_CLASS)) {
+            targetObject = DataTypeTransformer.getDate(value);
+        } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.TIME_CLASS)) {
+            targetObject = DataTypeTransformer.getTime(value);
+        } else if (javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BLOB_CLASS)) {
+            targetObject = DataTypeTransformer.getBlob(value);
+        } else if (javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.CLOB_CLASS)) {
+            targetObject = DataTypeTransformer.getClob(value);
+        } else {
+            String msg = JDBCPlugin.Util.getString("MMPreparedStatement.Err_transform_obj"); //$NON-NLS-1$
+            throw new TeiidSQLException(msg);
+        }
+
+        setObject(parameterIndex, targetObject);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to an object value
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param an object value to which the parameter value is to be set.
+     * @throws SQLException, if there is an error setting the parameter value
+     */
+    public void setObject(int parameterIndex, Object value) throws SQLException {
+        ArgCheck.isPositive(parameterIndex, JDBCPlugin.Util.getString("MMPreparedStatement.Invalid_param_index")); //$NON-NLS-1$
+
+        if(parameterMap == null){
+            parameterMap = new TreeMap<Integer, Object>();
+        }
+        
+        Object val = null;
+        if (serverCalendar != null && value instanceof java.util.Date) {
+            val = TimestampWithTimezone.create((java.util.Date)value, getDefaultCalendar().getTimeZone(), serverCalendar, value.getClass());
+        } else val = value;
+
+        parameterMap.put(new Integer(parameterIndex), val);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a short value. The parameter
+     * type is set to TINYINT
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param short value to which the parameter value is to be set.
+     * @throws SQLException, if there is an error setting the parameter value
+     */
+    public void setShort(int parameterIndex, short value) throws SQLException {
+        setObject(parameterIndex, new Short(value));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a String value. The parameter
+     * type is set to VARCHAR
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param String object to which the parameter value is to be set.
+     * @throws SQLException
+     */
+    public void setString(int parameterIndex, String value) throws SQLException {
+        setObject(parameterIndex, value);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a java.sql.Time object. The parameter
+     * type is set to TIME
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Time object to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setTime(int parameterIndex, java.sql.Time value) throws SQLException {
+        setTime(parameterIndex, value, null);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a java.sql.Time object. The parameter
+     * type is set to TIME
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Time object to which the parameter value is to be set.
+     * @param Calendar object to constrct Time(useful to get include timezone info)
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setTime(int parameterIndex, java.sql.Time x, java.util.Calendar cal) throws SQLException {
+
+       if (cal == null || x == null) {
+           setObject(parameterIndex, x);
+           return;
+       }
+               
+       // set the parameter on the stored procedure
+       setObject(parameterIndex, TimestampWithTimezone.createTime(x, cal.getTimeZone(), getDefaultCalendar()));
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a java.sql.Timestamp object. The
+     * parameter type is set to TIMESTAMP
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Timestamp object to which the parameter value is to be set.
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setTimestamp(int parameterIndex, java.sql.Timestamp value) throws SQLException {
+        setTimestamp(parameterIndex, value, null);
+    }
+
+    /**
+     * <p>Sets parameter number parameterIndex to x, a java.sql.Timestamp object. The
+     * parameter type is set to TIMESTAMP
+     * @param parameterIndex of the parameter whose value is to be set
+     * @param Timestamp object to which the parameter value is to be set.
+     * @param Calendar object to constrct timestamp(useful to get include timezone info)
+     * @throws SQLException, if parameter type/datatype do not match
+     */
+    public void setTimestamp(int parameterIndex, java.sql.Timestamp x, java.util.Calendar cal) throws SQLException {
+
+        if (cal == null || x == null) {
+            setObject(parameterIndex, x);
+            return;
+        }
+                
+        // set the parameter on the stored procedure
+        setObject(parameterIndex, TimestampWithTimezone.createTimestamp(x, cal.getTimeZone(), getDefaultCalendar()));
+    }
+
+    /**
+     * Sets the designated parameter to the given java.net.URL value. The driver
+     * converts this to an SQL DATALINK value when it sends it to the database.
+     * @param parameter int index
+     * @param x URL to be set
+     * @throws SQLException
+     */
+    public void setURL(int parameterIndex, URL x) throws SQLException {
+        setObject(parameterIndex, x);
+    }
+
+    List<List<Object>> getParameterValuesList() {
+    	if(batchParameterList == null || batchParameterList.isEmpty()){
+    		return Collections.emptyList();
+    	}
+    	return new ArrayList<List<Object>>(batchParameterList);
+    }
+    
+    List<Object> getParameterValues() {
+        if(parameterMap == null || parameterMap.isEmpty()){
+            return Collections.emptyList();
+        }
+        return new ArrayList<Object>(parameterMap.values());
+    }
+
+	public ParameterMetaData getParameterMetaData() throws SQLException {
+		if (parameterMetaData == null) {
+			//TODO: some of the base implementation of ResultSetMetadata could be on the MetadataProvider
+			this.parameterMetaData = new ParameterMetaDataImpl(new ResultSetMetaDataImpl(new MetadataProvider(getMetadataResults().getParameterMetadata())));
+		}
+		return parameterMetaData;
+	}
+
+    /**
+     * Exposed for unit testing 
+     */
+    void setServerCalendar(Calendar serverCalendar) {
+        this.serverCalendar = serverCalendar;
+    }
+
+	public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+		setObject(parameterIndex, xmlObject);
+	}
+
+	public void setArray(int parameterIndex, Array x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setAsciiStream(int parameterIndex, InputStream x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setAsciiStream(int parameterIndex, InputStream x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBinaryStream(int parameterIndex, InputStream x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBinaryStream(int parameterIndex, InputStream x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBlob(int parameterIndex, InputStream inputStream)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setCharacterStream(int parameterIndex, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setCharacterStream(int parameterIndex, Reader reader,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setClob(int parameterIndex, Reader reader) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setClob(int parameterIndex, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNCharacterStream(int parameterIndex, Reader value)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNCharacterStream(int parameterIndex, Reader value,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public void setNClob(int parameterIndex, NClob value) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNClob(int parameterIndex, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setNString(int parameterIndex, String value)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void setRef(int parameterIndex, Ref x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public void setRowId(int parameterIndex, RowId x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ResultSetImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,1778 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
+
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.lob.LobChunkInputStream;
+import org.teiid.client.lob.StreamingLobChunckProducer;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.BatchResults.Batch;
+import org.teiid.jdbc.BatchResults.BatchFetcher;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.types.BlobImpl;
+import com.metamatrix.common.types.BlobType;
+import com.metamatrix.common.types.ClobImpl;
+import com.metamatrix.common.types.ClobType;
+import com.metamatrix.common.types.InputStreamFactory;
+import com.metamatrix.common.types.SQLXMLImpl;
+import com.metamatrix.common.types.Streamable;
+import com.metamatrix.common.types.XMLType;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.common.util.TimestampWithTimezone;
+
+/**
+ * <p>
+ * The MMResultSet is the way query results are returned to the requesting
+ * client based upon a query given to the server. This abstract class that
+ * implements java.sql.ResultSet. This class represents access to results
+ * produced by any of the classes on the driver.
+ * </p>
+ */
+
+public class ResultSetImpl extends WrapperImpl implements ResultSet, BatchFetcher {
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+
+	private static final int BEFORE_FIRST_ROW = 0;
+
+	// the object which was last read from Results
+	private Object currentValue;
+
+	// This object represents metadata for this result set.
+	private ResultSetMetaData rmetadata;
+	// Statement that causes this results
+	private StatementImpl statement;
+
+    // Cursor related state
+    private int cursorType;
+    private boolean isClosed;
+
+    // reuse the original request's state
+    private long requestID;
+    private BatchResults batchResults;
+    private int columnCount;
+    private int resultColumns;
+    private int parameters;
+    private TimeZone serverTimeZone;
+    private Map updatedPlanDescription;
+    private int maxFieldSize;
+    private int fetchSize;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param resultsMsg
+	 * @param statement
+	 * @throws SQLException
+	 */
+	ResultSetImpl(ResultsMessage resultsMsg, StatementImpl statement) throws SQLException {
+		this(resultsMsg, statement, null, 0);
+	}
+
+	ResultSetImpl(ResultsMessage resultsMsg, StatementImpl statement,
+			ResultSetMetaData metadata, int parameters) throws SQLException {
+		this.statement = statement;
+		this.parameters = parameters;
+		// server latency-related timestamp
+        this.requestID = statement.getCurrentRequestID();
+        this.cursorType = statement.getResultSetType();
+        this.batchResults = new BatchResults(this, getCurrentBatch(resultsMsg), this.cursorType == ResultSet.TYPE_FORWARD_ONLY ? 1 : BatchResults.DEFAULT_SAVED_BATCHES);
+        accumulateWarnings(resultsMsg);
+        this.serverTimeZone = statement.getServerTimeZone();
+
+		if (metadata == null) {
+			MetadataProvider provider = new DeferredMetadataProvider(resultsMsg.getColumnNames(),
+							resultsMsg.getDataTypes(), statement,
+							statement.getCurrentRequestID());
+			rmetadata = new ResultSetMetaDataImpl(provider);
+		} else {
+			rmetadata = metadata;
+		}
+        // Cache the column count and isLOB values since every call to getObject uses these.
+		this.columnCount = rmetadata.getColumnCount();
+		
+		this.resultColumns = columnCount - parameters;
+		if (this.parameters > 0) {
+			rmetadata = new FilteredResultsMetadata(rmetadata, resultColumns);
+		}
+		this.fetchSize = statement.getFetchSize();
+	}
+	
+	public void setMaxFieldSize(int maxFieldSize) {
+		this.maxFieldSize = maxFieldSize;
+	}
+	
+    /**
+     * Close this result set.
+     */
+    public void close() throws SQLException{
+    	if(!isClosed) {
+            // close the the server's statement object (if necessary)
+    		if(this.requestID >= 0){
+	            try {
+					this.statement.getDQP().closeRequest(requestID);
+				} catch (MetaMatrixProcessingException e) {
+					throw TeiidSQLException.create(e);
+				} catch (MetaMatrixComponentException e) {
+					throw TeiidSQLException.create(e);
+				}
+    		}
+            isClosed = true;
+        }
+    }
+    
+	public boolean isClosed() throws SQLException {
+		return isClosed;
+	}
+    
+    protected void checkClosed() throws SQLException {
+    	if (isClosed) {
+    		String msg = JDBCPlugin.Util
+    				.getString("MMResultSet.Cant_call_closed_resultset"); //$NON-NLS-1$
+    		throw new TeiidSQLException(msg);
+    	}
+    }
+    
+     /**
+      * Return the value for output/return parameter given the index
+      * of the parameter in the ResultSet
+      * @param index Index of the parameter to be retrieved.
+      */
+     Object getOutputParamValue(int index) throws SQLException {
+         if (index <= resultColumns || index > resultColumns + parameters) {
+             throw new TeiidSQLException(JDBCPlugin.Util.getString("StoredProcedureResultsImpl.Invalid_parameter_index__{0}_2", index)); //$NON-NLS-1$
+         }
+         // Mark the row we're on
+         final int originalRow = getAbsoluteRowNumber();
+         
+         this.batchResults.absolute(-1);
+         try {
+         	return getObjectDirect(index);
+         } finally {
+         	this.batchResults.absolute(originalRow);
+         }
+     }
+     
+     /**
+      * <p>Get a java object based on the column index for the current row.</p>
+      * @param The index of the column whose value needs to be fetched.
+      * @return The value of the column as an object.
+      * @throws SQLException if a results access error occurs or transform fails.
+      */
+     public Object getObject(int column) throws SQLException {
+         if (isAfterLast()) {
+             throw new TeiidSQLException(JDBCPlugin.Util.getString("StoredProcedureResultsImpl.ResultSet_cursor_is_after_the_last_row._1")); //$NON-NLS-1$
+         }
+         // only get the Object of the result set
+         if(column > resultColumns){
+             throw new TeiidSQLException(JDBCPlugin.Util.getString("ResultsImpl.Invalid_col_index", column)); //$NON-NLS-1$
+         }
+         return getObjectDirect(column);
+     }
+
+    /**
+     * Get fetch size that will be used if this result set is backed
+     * by a cursor.  This may be the hint fetch size provided by
+     * {@link com.metamatrix.jdbc.ResultsImpl#getFetchSize} or it may
+     * have been reset by the server.
+     */
+    public int getFetchSize() throws SQLException {
+        return this.fetchSize;
+    }
+
+    /**
+     * Move row pointer forward one row.  This may cause the cursor
+     * to fetch more rows.
+     * @return True if the current index is on a valid row, false if
+     * the pointer is past the end of the rows
+     * @throws SQLException if this result set has an exception
+     */
+    public boolean next() throws SQLException {
+        checkClosed();
+        if (hasNext()) {
+    		return batchResults.next();
+    	}
+        batchResults.next();
+    	return false;
+    }
+
+    /**
+     * Move row pointer backward one row.  This may cause the cursor
+     * to fetch more rows.
+     * @return True if the current index is on a valid row, false if
+     * the pointer is before the beginning of the rows
+     * @throws SQLException if this result set has an exception
+     */
+    public boolean previous() throws SQLException {
+        checkClosed();
+        checkNotForwardOnly();
+        return batchResults.previous();
+    }
+
+    /**
+     * Get current row pointer.
+     * @return Index of current row
+     * @throws SQLException if this result set has an exception
+     */
+    public int getRow() throws SQLException {
+        checkClosed();
+        if (isAfterLast()) {
+        	return 0;
+        }
+        return getAbsoluteRowNumber();
+    }
+
+    /**
+     * Get the value of the current row at the column index specified.
+     * @param column Column index
+     * @return Value at column, which may be null
+     * @throws SQLException if this result set has an exception
+     */
+    public Object getObjectDirect(int column) throws SQLException {
+    	checkClosed();
+    	if(column < 1 || column > columnCount) {
+            throw new IllegalArgumentException(JDBCPlugin.Util.getString("ResultsImpl.Invalid_col_index", column)); //$NON-NLS-1$
+        }
+        List cursorRow = batchResults.getCurrentRow();
+        
+        if (cursorRow == null) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("ResultsImpl.The_cursor_is_not_on_a_valid_row._1")); //$NON-NLS-1$
+        }
+
+        // defect 13539 - set the currentValue (defined in MMResultSet) so that wasNull() accurately returns whether this value was null
+        currentValue = cursorRow.get(column-1);
+            
+        if (currentValue instanceof Streamable) {
+        	if (Boolean.getBoolean(Streamable.FORCE_STREAMING)) {
+        		Object reference = ((Streamable)currentValue).getReference();
+            	if (reference != null) {
+            		currentValue = reference;
+            		return currentValue;
+            	}
+        	}
+            if(currentValue instanceof ClobType){
+            	currentValue = new ClobImpl(createInputStreamFactory((ClobType)currentValue), ((ClobType)currentValue).getLength());
+            }
+            else if (currentValue instanceof BlobType) {
+            	InputStreamFactory isf = createInputStreamFactory((BlobType)currentValue);
+            	isf.setLength(((BlobType)currentValue).getLength());
+            	currentValue = new BlobImpl(isf);
+            }
+            else if (currentValue instanceof XMLType) {
+            	currentValue = new SQLXMLImpl(createInputStreamFactory((XMLType)currentValue));
+            } 
+        } 
+        else if (currentValue instanceof java.util.Date) {
+            return TimestampWithTimezone.create((java.util.Date)currentValue, serverTimeZone, getDefaultCalendar(), currentValue.getClass());
+        }
+        else if (maxFieldSize > 0 && currentValue instanceof String) {
+        	String val = (String)currentValue;
+        	currentValue = val.substring(0, Math.min(maxFieldSize/2, val.length()));
+        }
+        return currentValue;
+    }
+
+	private InputStreamFactory createInputStreamFactory(Streamable<?> type) {
+		final StreamingLobChunckProducer.Factory factory = new StreamingLobChunckProducer.Factory(this.statement.getDQP(), this.requestID, type);
+		InputStreamFactory isf = new InputStreamFactory(Streamable.ENCODING) {
+			@Override
+			public InputStream getInputStream() throws IOException {
+				return new LobChunkInputStream(factory.getLobChunkProducer());
+			}
+		};
+		return isf;
+	}
+
+    /**
+     * Get all values in current record in column order
+     * @return List of Object values in current row
+     * @throws SQLException if an access error occurs.
+     */
+    public List getCurrentRecord() throws SQLException {
+    	checkClosed();
+        List wholeRecord = batchResults.getCurrentRow();
+        return wholeRecord.subList(0, wholeRecord.size() - getOffset());
+    }
+    /*
+     * @see java.sql.ResultSet#getType()
+     */
+    public int getType() throws SQLException {
+        return this.cursorType;
+    }
+
+    public boolean absolute( int row) throws SQLException {
+        checkClosed();
+        checkNotForwardOnly();
+        return batchResults.absolute(row, getOffset());
+    }
+    
+    protected Map getUpdatedPlanDescription() {
+    	return updatedPlanDescription;
+    }
+    
+    public Batch requestBatch(int beginRow) throws SQLException{
+    	logger.fine("CursorResultsImpl.requestBatch] thread name: " + Thread.currentThread().getName() + " requestID: " + requestID + " beginRow: " + beginRow ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    	checkClosed();
+        try {
+        	ResultsFuture<ResultsMessage> results = statement.getDQP().processCursorRequest(requestID, beginRow, fetchSize);
+        	int timeoutSeconds = statement.getQueryTimeout();
+        	if (timeoutSeconds == 0) {
+        		timeoutSeconds = Integer.MAX_VALUE;
+        	}
+        	ResultsMessage currentResultMsg = results.get(timeoutSeconds, TimeUnit.SECONDS);
+    		this.accumulateWarnings(currentResultMsg);
+    		this.updatedPlanDescription = currentResultMsg.getPlanDescription();
+    		return getCurrentBatch(currentResultMsg);
+        } catch (MetaMatrixProcessingException e) {
+			throw TeiidSQLException.create(e);
+		} catch (InterruptedException e) {
+			throw TeiidSQLException.create(e);
+		} catch (ExecutionException e) {
+			throw TeiidSQLException.create(e);
+		} catch (TimeoutException e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+	private Batch getCurrentBatch(ResultsMessage currentResultMsg) {
+		boolean isLast = currentResultMsg.getResults().length == 0 || currentResultMsg.getFinalRow() == currentResultMsg.getLastRow();
+		return new Batch(currentResultMsg.getResults(), currentResultMsg.getFirstRow(), currentResultMsg.getLastRow(), isLast);
+	}
+    
+	protected int getFinalRowNumber() {
+    	return Math.max(-1, batchResults.getFinalRowNumber() - getOffset());
+	}
+
+	protected boolean hasNext() throws SQLException {
+		return batchResults.hasNext(getOffset() + 1);
+	}
+	
+	protected int getOffset() {
+		return parameters > 0 ? 1 : 0;
+	}
+
+	protected int getAbsoluteRowNumber() {
+		return batchResults.getCurrentRowNumber();
+	}
+
+	public void cancelRowUpdates() throws SQLException {
+		// do nothing.
+		checkClosed(); // check to see if the ResultSet is closed
+	}
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+	public void clearWarnings() throws SQLException {
+		// do nothing
+		checkClosed(); // check to see if the ResultSet is closed
+	}
+
+	public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getBigDecimal(getObject(columnIndex));
+	}
+
+	public BigDecimal getBigDecimal(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getBigDecimal(findColumn(columnName));
+	}
+
+	public BigDecimal getBigDecimal(int columnIndex, int scale)
+			throws SQLException {
+
+		// do the necessary transformation depending on the datatype of the
+		// object at the given index.
+		BigDecimal bigDecimalObject = DataTypeTransformer
+				.getBigDecimal(getObject(columnIndex));
+		
+		if (bigDecimalObject == null) {
+			return null;
+		}
+
+		// set the scale on the bigDecimal
+		return bigDecimalObject.setScale(scale);
+	}
+
+	public BigDecimal getBigDecimal(String columnName, int scale)
+			throws SQLException {
+		// find the columnIndex for the given column name.
+		return getBigDecimal(findColumn(columnName), scale);
+	}
+
+	public java.io.InputStream getBinaryStream(int columnIndex)
+			throws SQLException {
+		Object value = getObject(columnIndex);
+		if (value == null) {
+			return null;
+		}
+
+		if (value instanceof Blob) {
+			return ((Blob) value).getBinaryStream();
+		}
+		
+		if (value instanceof SQLXML) {
+			return ((SQLXML)value).getBinaryStream();
+		}
+
+		throw new TeiidSQLException(JDBCPlugin.Util.getString("MMResultSet.cannot_convert_to_binary_stream")); //$NON-NLS-1$
+	}
+
+	public java.io.InputStream getBinaryStream(String columnName)
+			throws SQLException {
+		return getBinaryStream(findColumn(columnName));
+	}
+
+	public Blob getBlob(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getBlob(getObject(columnIndex));
+	}
+
+	public Blob getBlob(String columnName) throws SQLException {
+		return getBlob(findColumn(columnName));
+	}
+
+	public boolean getBoolean(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getBoolean(getObject(columnIndex));
+	}
+
+	public boolean getBoolean(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getBoolean(findColumn(columnName));
+	}
+
+	public byte getByte(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getByte(getObject(columnIndex));
+	}
+
+	public byte getByte(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getByte(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as an array of byte
+	 * values
+	 * 
+	 * @param columnIndex
+	 * 		The column position in the current row whose value is to be read.
+	 * @return The value of the column at columnIndex as an array of bytes.
+	 * @throws SQLException
+	 * 		if there is an error accessing or converting the result value
+	 */
+	public byte[] getBytes(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getBytes(getObject(columnIndex));
+	}
+
+	/**
+	 * This method will return the value in the current row as an array of byte
+	 * values
+	 * 
+	 * @param columnName
+	 * 		The column name in the current row whose value is to be updated.
+	 * @return byte[]. The value of the column at columnIndex as an array of
+	 * 	bytes.
+	 * @throws SQLException
+	 * 		if there is an error accessing or converting the result value
+	 */
+	public byte[] getBytes(String columnName) throws SQLException {
+		return getBytes(findColumn(columnName));
+	}
+
+	/**
+	 * Get the concurrency type for this ResultSet object. The concurrency was
+	 * set by the Statement object. The possible concurrency types are
+	 * CONCUR_READ_ONLY and CONCUR_UPDATABLE.
+	 * 
+	 * @return The resultSets are not updatable, this method returns
+	 * 	CONCUR_READ_ONLY.
+	 * @throws SQLException
+	 * 		if the there is an error accesing results
+	 */
+	public int getConcurrency() throws SQLException {
+
+		checkClosed(); // check to see if the ResultSet is closed
+		return ResultSet.CONCUR_READ_ONLY;
+	}
+
+	/**
+	 * This method will attempt to return the value contained at the index as a
+	 * java.io.Reader object.
+	 * 
+	 * @param columnIndex
+	 * 		The column position in the current row whose value is to be read.
+	 * @return The value of the column as a java.io.Reader object.
+	 */
+	public java.io.Reader getCharacterStream(int columnIndex)
+			throws SQLException {
+		Object value = getObject(columnIndex);
+		if (value == null) {
+			return null;
+		}
+
+		if (value instanceof Clob) {
+			return ((Clob) value).getCharacterStream();
+		}
+		
+		if (value instanceof SQLXML) {
+			return ((SQLXML)value).getCharacterStream();
+		}
+		
+		return new StringReader(getString(columnIndex));
+	}
+
+	/**
+	 * This method will attempt to return the value at the designated column
+	 * determined by the columName as a java.io.Reader object.
+	 * 
+	 * @param columnName
+	 * 		The column name in the current row whose value is to be updated.
+	 * @return The value of the column as a java.io.Reader object.
+	 */
+	public java.io.Reader getCharacterStream(String columnName)
+			throws SQLException {
+		return getCharacterStream(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a Date object.
+	 * This will use the timeZone info of the calendar object.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @param Calender
+	 * 		object used to get the date value.
+	 * @return The value of the column as a Date object.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+		Date value = DataTypeTransformer.getDate(getObject(columnIndex));
+
+		if (value != null && cal != null) {
+			value = TimestampWithTimezone.createDate(value,
+					getDefaultCalendar().getTimeZone(), cal);
+		}
+
+		return value;
+	}
+
+	/**
+	 * Get the Date value for the given column.
+	 * 
+	 * @param columnName
+	 * 		. The name of the column whose value needs to be fetched.
+	 * @param Calender
+	 * 		object used to get the date value.
+	 * @return value of the column as an int.
+	 * @throws SQLException
+	 * 		unable to obtain date value for the given column.
+	 */
+	public Date getDate(String columnName, Calendar cal) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getDate(findColumn(columnName), cal);
+	}
+
+	/**
+	 * This method will return the value in the current row as a Date object.
+	 * This will assume the default timeZone.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a Date object.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public Date getDate(int columnIndex) throws SQLException {
+		return getDate(columnIndex, null);
+	}
+
+	/**
+	 * Get the column value as a Date object
+	 * 
+	 * @param name
+	 * 		of the column in the resultset whose value is to be fetched.
+	 * @return value of the column as an int.
+	 * @throw a SQLException if a resultSet access error occurs.
+	 */
+	public Date getDate(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getDate(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a double value.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a double value.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public double getDouble(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getDouble(getObject(columnIndex));
+	}
+
+	/**
+	 * Get a double value based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column in the resultset whose value is to be fetched.
+	 * @return value of the column as a double.
+	 * @throw a SQLException if a resultSet access error occurs.
+	 */
+	public double getDouble(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getDouble(findColumn(columnName));
+	}
+
+	/**
+	 * Gets the direction suggested to the driver as the direction in which to
+	 * fetch rows.
+	 * 
+	 * @return fetch direction for this ResultSet. This cannot be set and is
+	 * 	alwayd FETCH_FORWARD.
+	 * @throws SQLException
+	 */
+	public int getFetchDirection() throws SQLException {
+		checkClosed(); // check to see if the ResultSet is closed
+		return ResultSet.FETCH_FORWARD;
+	}
+
+	/**
+	 * This method will return the value in the current row as a float value.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a float value.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public float getFloat(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getFloat(getObject(columnIndex));
+	}
+
+	/**
+	 * Get a float value based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column in the resultset whose value is to be fetched.
+	 * @return value of the column as a float.
+	 * @throw a SQLException if a resultSet access error occurs.
+	 */
+	public float getFloat(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getFloat(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a int value.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a int value.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public int getInt(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getInteger(getObject(columnIndex));
+	}
+
+	/**
+	 * Get an integer based on the column index.
+	 * 
+	 * @param name
+	 * 		of the column in the resultset whose value is to be fetched.
+	 * @return value of the column as an int.
+	 * @throw a SQLException if a resultSet access error occurs.
+	 */
+	public int getInt(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getInt(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a long value.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a long value.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public long getLong(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getLong(getObject(columnIndex));
+	}
+
+	/**
+	 * Get a long based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column in the resultset whose value is to be fetched.
+	 * @return value of the column as a long.
+	 * @throw a SQLException if a resultSet access error occurs.
+	 */
+	public long getLong(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getLong(findColumn(columnName));
+	}
+
+	/**
+	 * Get a java object based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column in the resultset whose value is to be fetched.
+	 * @return object which gives the column value.
+	 * @throw a SQLException if a resultSet access error occurs.
+	 */
+	public Object getObject(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getObject(findColumn(columnName));
+	}
+
+	/**
+	 * Get a primitive short based on the column index.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a short value.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public short getShort(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getShort(getObject(columnIndex));
+	}
+
+	/**
+	 * Get a short based on the column name.
+	 * 
+	 * @param String
+	 * 		representing name of the column.
+	 * @return short value of the column.
+	 * @throws SQLException
+	 * 		if a results access error occurs.
+	 */
+	public short getShort(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getShort(findColumn(columnName));
+	}
+
+	/**
+	 * Get a String based on the column index.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a string value.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public String getString(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getString(getObject(columnIndex));
+	}
+
+	/**
+	 * Get a string based on the column name.
+	 * 
+	 * @param String
+	 * 		representing name of the column.
+	 * @return String value of the column.
+	 * @throws SQLException
+	 * 		if a results access error occurs.
+	 */
+	public String getString(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getString(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a Time object.
+	 * This will assume the default timeZone.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a Time object.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public Time getTime(int columnIndex) throws SQLException {
+		return getTime(columnIndex, null);
+	}
+
+	/**
+	 * Get a java.sql.Time based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column whose value is to be fetched as a timestamp
+	 * @return value of the column as a Timestamp object
+	 * @throws SQLException
+	 * 		if a results access error occurs.
+	 */
+	public Time getTime(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getTime(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a Time object.
+	 * This will use the timeZone info of the calendar object.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @param Calendar
+	 * 		object to be used to construct the Time object.
+	 * @return The value of the column as a Time object.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+		Time value = DataTypeTransformer.getTime(getObject(columnIndex));
+
+		if (value != null && cal != null) {
+			value = TimestampWithTimezone.createTime(value,
+					getDefaultCalendar().getTimeZone(), cal);
+		}
+
+		return value;
+	}
+
+	/**
+	 * Get a java.sql.Time based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column whose value is to be fetched as a timestamp
+	 * @param calender
+	 * 		object to include the timezone info in the object returned
+	 * @return value of the column as a Timestamp object
+	 * @throws SQLException
+	 * 		if a results access error occurs.
+	 */
+	public Time getTime(String columnName, Calendar cal) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getTime((findColumn(columnName)), cal);
+	}
+
+	/**
+	 * This method will return the value in the current row as a Timestamp
+	 * object. This will assume the default timeZone.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @return The value of the column as a Timestamp object.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public Timestamp getTimestamp(int columnIndex) throws SQLException {
+		return getTimestamp(columnIndex, null);
+	}
+
+	/**
+	 * Get a java.sql.Timestamp based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column whose value is to be fetched as a timestamp
+	 * @return value of the column as a Timestamp object
+	 * @throws SQLException
+	 * 		if a results access error occurs.
+	 */
+	public Timestamp getTimestamp(String columnName) throws SQLException {
+		// find the columnIndex for the given column name.
+		return getTimestamp(findColumn(columnName));
+	}
+
+	/**
+	 * This method will return the value in the current row as a Timestamp
+	 * object. This will use the timeZone info of the calendar object.
+	 * 
+	 * @param The
+	 * 		index of the column whose value needs to be fetched.
+	 * @param Calendar
+	 * 		object to be used to construct the Timestamp object.
+	 * @return The value of the column as a Timestamp object.
+	 * @throws SQLException
+	 * 		if a results access error occurs or transform fails.
+	 */
+	public Timestamp getTimestamp(int columnIndex, Calendar cal)
+			throws SQLException {
+		Timestamp value = DataTypeTransformer.getTimestamp(getObject(columnIndex));
+
+		if (value != null && cal != null) {
+			value = TimestampWithTimezone.createTimestamp(value,
+					getDefaultCalendar().getTimeZone(), cal);
+		}
+
+		return value;
+	}
+
+	/**
+	 * Get a java.sql.Timestamp based on the column name.
+	 * 
+	 * @param name
+	 * 		of the column whose value is to be fetched as a timestamp
+	 * @param calender
+	 * 		object to include the timezone info in the object returned
+	 * @return value of the column as a Timestamp object
+	 * @throws SQLException
+	 * 		if a results access error occurs.
+	 */
+	public Timestamp getTimestamp(String columnName, Calendar cal)
+			throws SQLException {
+		// find the columnIndex for the given column name.
+		return getTimestamp(findColumn(columnName), cal);
+	}
+
+	/**
+	 * Moves the cursor to the remembered cursor position, usually the current
+	 * row. This method does not have any effect if the cursor is not on the
+	 * insert row. ResultSet cannot currently be updated.
+	 */
+	public void moveToCurrentRow() throws SQLException {
+		// do nothing
+	}
+
+	/**
+	 * This will return a boolean value if the last column that was read had a
+	 * value equal to null. If the last column read was null return true, else
+	 * return false.
+	 * 
+	 * @return A boolean value showing if the lastvalue read in was null or not.
+	 * @throws SQLException
+	 */
+	public boolean wasNull() throws SQLException {
+		
+		checkClosed(); // check to see if the ResultSet is closed
+
+		return currentValue == null;
+	}
+
+	protected void accumulateWarnings(ResultsMessage resultsMsg) {
+		this.statement.accumulateWarnings(resultsMsg.getWarnings());
+	}
+
+	/**
+	 * <p>
+	 * This method returns the meta data of the result set, such as the number,
+	 * types and properties of this resultSets columns.
+	 * </p>
+	 * 
+	 * @return ResultSerMetaData object for these results.
+	 * @throws SQLException
+	 * 		if results access error occurs
+	 */
+	public ResultSetMetaData getMetaData() throws SQLException {
+		checkClosed();
+		return rmetadata;
+	}
+
+	/**
+	 * Retrieves the RequestID for the query that created this ResultSet.
+	 * 
+	 * @return The requestID for the query that created these results
+	 * @throws SQLException
+	 */
+	public String getCursorName() throws SQLException {
+		return null;
+	}
+
+	/**
+	 * <p>
+	 * Retrieves the Statement object that produced this ResultSet object.
+	 * 
+	 * @return a Statement object.
+	 * 	</p>
+	 * @throws SQLException
+	 * 		if the there is an error accesing results
+	 */
+	public StatementImpl getStatement() throws SQLException {
+		checkClosed();
+		return statement;
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		checkClosed();
+
+		return null;
+	}
+
+	/**
+	 * True if current record is the first in the result set.
+	 * 
+	 * @return True if current row is first
+	 * @throws QueryResultsException
+	 * 		if this result set has an exception
+	 * @throws InvalidatedResultsException
+	 * 		if the results were obtained during a transaction and the
+	 * 		transaction has been rolled back
+	 */
+	public boolean isFirst() throws SQLException {
+		return this.getAbsoluteRowNumber() == BEFORE_FIRST_ROW + 1 && hasNext();
+	}
+
+	/**
+	 * True if current record is the last in the result set.
+	 * 
+	 * @return True if current row is last
+	 * @throws QueryResultsException
+	 * 		if this result set has an exception
+	 * @throws InvalidatedResultsException
+	 * 		if the results were obtained during a transaction and the
+	 * 		transaction has been rolled back
+	 */
+	public boolean isLast() throws SQLException {
+		return !hasNext() && this.getAbsoluteRowNumber() > BEFORE_FIRST_ROW && this.getAbsoluteRowNumber() == getFinalRowNumber();
+	}
+	
+	/**
+	 * <p>
+	 * Determines whether the cursor is after the last row in this ResultSet
+	 * object. This method should be called only if the result set is
+	 * scrollable.
+	 * </p>
+	 * 
+	 * @return true if the cursor is after the last row in the resultSet.
+	 * @throws SQLException
+	 */
+	public boolean isAfterLast() throws SQLException {
+		// return true if the current row has a next row
+		// it is also not the last
+		return !hasNext() && this.getAbsoluteRowNumber() > BEFORE_FIRST_ROW && this.getAbsoluteRowNumber() > getFinalRowNumber();
+	}
+
+	/**
+	 * <p>
+	 * Determines whether the cursor is before the first row in this ResultSet
+	 * object. This method should be called only if the result set is
+	 * scrollable.
+	 * </p>
+	 * 
+	 * @return true if the cursor is before the last row in the resultSet;false
+	 * 	if the cursor is at any other position or the result set contains no
+	 * 	rows.
+	 * @throws SQLException
+	 */
+	public boolean isBeforeFirst() throws SQLException {
+		// return true if there are rows and the current row is before first
+		return getAbsoluteRowNumber() == BEFORE_FIRST_ROW && hasNext();
+	}
+
+	/**
+	 * <p>
+	 * Moves the cursor a number of rows relative to the current row in this
+	 * ResultSet object. The number of rows may be positive or negative.
+	 * </p>
+	 * 
+	 * @param number
+	 * 		of rows to move relative to the present row.
+	 * @return true if the cursor is on a valid row in the resultSet.
+	 * @throws SQLException
+	 * 		if the there is an error accessing results
+	 */
+	public boolean relative(int rows) throws SQLException {
+		if (isBeforeFirst() || isAfterLast() || getFinalRowNumber() == 0) {
+			throw new TeiidSQLException(
+					JDBCPlugin.Util
+							.getString("ResultsImpl.The_cursor_is_not_on_a_valid_row._1")); //$NON-NLS-1$
+		}
+
+		checkNotForwardOnly();
+		
+    	return this.absolute(Math.max(0, getAbsoluteRowNumber() + rows));
+	}
+	
+	/**
+	 * <p>
+	 * Moves the cursor to the last row in the in this ResultSet object. This
+	 * method should be called only if the result set is scrollable.
+	 * </p>
+	 * 
+	 * @return true if the cursor is on a validRow, false otherwise or if no
+	 * 	rows exist.
+	 * @throws SQLException
+	 * 		if the type of the ResultSet is TYPE_FORWARD_ONLY
+	 */
+	public boolean last() throws SQLException {
+		checkNotForwardOnly();
+		
+    	return absolute(-1);
+	}
+
+	protected void checkNotForwardOnly() throws SQLException {
+		if (getType() == ResultSet.TYPE_FORWARD_ONLY) {
+			String msg = JDBCPlugin.Util
+					.getString("ResultsImpl.Op_invalid_fwd_only"); //$NON-NLS-1$
+			throw new TeiidSQLException(msg);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Moves the cursor to the end of the result set, just after the last row.
+	 * Has no effect if the result set contains no rows.
+	 * </p>
+	 * 
+	 * @throws SQLException
+	 * 		if a results access error occurs or the result set type is
+	 * 		TYPE_FORWARD_ONLY
+	 */
+	public void afterLast() throws SQLException {
+		if (last()) {
+    		next();
+    	}
+	}
+
+	/**
+	 * <p>
+	 * Moves the cursor to the front of the result set, just before the first
+	 * row. Has no effect if the result set contains no rows.
+	 * </p>
+	 * 
+	 * @exception SQLException
+	 * 		if a results can not be accessed or the result set type is
+	 * 		TYPE_FORWARD_ONLY
+	 */
+	public void beforeFirst() throws SQLException {
+		if (first()) {
+    		previous();
+    	}
+	}
+	
+	/**
+	 * <p>
+	 * Moves the cursor to the first row in this ResultSet object.
+	 * </p>
+	 * 
+	 * @return true if the cursor is on valid row, false if there are no rows in
+	 * 	the resultset.
+	 * @throws SQLException
+	 * 		if the ResulSet is of TYPE_FORWARD_ONLY.
+	 */
+	public boolean first() throws SQLException {
+		checkNotForwardOnly();
+		return absolute(1);
+	}
+
+	/**
+	 * <p>
+	 * This method returns the integer that represents which column represents
+	 * the column name parameter.
+	 * </p>
+	 * 
+	 * @param Name
+	 * 		of the column whose position is to be returned.
+	 * @return Position of column amoung the columns in the ResultSet.
+	 * @throws SQLException
+	 * 		if a database access error occurs.
+	 */
+	public int findColumn(String columnName) throws SQLException {
+		checkClosed();
+
+		// get the column index using ResultsMetadata object
+		return findColumnIndex(columnName);
+	}
+
+	protected int findColumnIndex(String columnName) throws SQLException {
+		int colCount = getMetaData().getColumnCount();
+		for (int i = 1; i <= colCount; i++) {
+			if (getMetaData().getColumnName(i).equalsIgnoreCase(columnName)) {
+				return i;
+			}
+		}
+
+		String msg = JDBCPlugin.Util.getString(
+				"MMResultsImpl.Col_doesnt_exist", columnName); //$NON-NLS-1$
+		throw new TeiidSQLException(msg);
+	}
+		
+	protected Calendar getDefaultCalendar() {
+		return statement.getDefaultCalendar();
+	}
+
+	public void deleteRow() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public Array getArray(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public Array getArray(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public InputStream getAsciiStream(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public InputStream getAsciiStream(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public Clob getClob(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getClob(getObject(columnIndex));
+	}
+	
+	public SQLXML getSQLXML(int columnIndex) throws SQLException {
+		return DataTypeTransformer.getSQLXML(getObject(columnIndex));
+	}
+
+	public Clob getClob(String columnLabel) throws SQLException {
+		return getClob(findColumn(columnLabel));
+	}
+
+	
+	public int getHoldability() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Reader getNCharacterStream(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public Reader getNCharacterStream(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public NClob getNClob(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public NClob getNClob(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+	
+	public String getNString(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public String getNString(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	
+	public Object getObject(int columnIndex, Map<String, Class<?>> map)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public Object getObject(String columnLabel, Map<String, Class<?>> map)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public Ref getRef(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public Ref getRef(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	//## JDBC4.0-begin ##
+	public RowId getRowId(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	//## JDBC4.0-begin ##
+	public RowId getRowId(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public SQLXML getSQLXML(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public InputStream getUnicodeStream(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public URL getURL(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public URL getURL(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void insertRow() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void moveToInsertRow() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void refreshRow() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public boolean rowDeleted() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public boolean rowInserted() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public boolean rowUpdated() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void setFetchDirection(int direction) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void setFetchSize(int rows) throws SQLException {
+		checkClosed();
+        if ( rows < 0 ) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Invalid_fetch_size")); //$NON-NLS-1$
+        }
+        // sets the fetch size on this statement
+        if (rows == 0) {
+            this.fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+        } else {
+            this.fetchSize = rows;
+        }
+	}
+
+	public void updateArray(int columnIndex, Array x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateArray(String columnLabel, Array x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateAsciiStream(int columnIndex, InputStream x, int length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public void updateAsciiStream(String columnLabel, InputStream x, int length)
+		throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public void updateAsciiStream(int columnIndex, InputStream x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateAsciiStream(int columnIndex, InputStream x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateAsciiStream(String columnLabel, InputStream x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateAsciiStream(String columnLabel, InputStream x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateBigDecimal(int columnIndex, BigDecimal x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateBigDecimal(String columnLabel, BigDecimal x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateBinaryStream(int columnIndex, InputStream x, int length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public void updateBinaryStream(String columnLabel, InputStream x, int length)
+		throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+
+	public void updateBinaryStream(int columnIndex, InputStream x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateBinaryStream(int columnIndex, InputStream x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateBinaryStream(String columnLabel, InputStream x,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateBinaryStream(String columnLabel, InputStream x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateBlob(int columnIndex, Blob x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public void updateBlob(String columnLabel, Blob x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateBlob(int columnIndex, InputStream inputStream, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateBlob(int columnIndex, InputStream inputStream)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	
+	public void updateBlob(String columnLabel, InputStream inputStream,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	
+	public void updateBlob(String columnLabel, InputStream inputStream)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	
+	public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateBoolean(String columnLabel, boolean x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateByte(int columnIndex, byte x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateByte(String columnLabel, byte x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	
+	public void updateCharacterStream(int columnIndex, Reader x, int length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public void updateCharacterStream(String columnLabel, Reader reader,
+			int length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}	
+
+	public void updateCharacterStream(int columnIndex, Reader x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateCharacterStream(int columnIndex, Reader x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateCharacterStream(String columnLabel, Reader reader,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateCharacterStream(String columnLabel, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateClob(int columnIndex, Clob x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateClob(String columnLabel, Clob x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+	
+	public void updateClob(int columnIndex, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateClob(int columnIndex, Reader reader) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateClob(String columnLabel, Reader reader, long length)
+		throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateClob(String columnLabel, Reader reader)
+		throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateDate(int columnIndex, Date x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateDate(String columnLabel, Date x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateDouble(int columnIndex, double x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateDouble(String columnLabel, double x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}		
+
+	public void updateFloat(int columnIndex, float x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateFloat(String columnLabel, float x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateInt(int columnIndex, int x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateInt(String columnLabel, int x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateLong(int columnIndex, long x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateLong(String columnLabel, long x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateNCharacterStream(int columnIndex, Reader x, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+		
+	}
+
+	public void updateNCharacterStream(int columnIndex, Reader x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+		
+	}
+
+	public void updateNCharacterStream(String columnLabel, Reader reader,
+			long length) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateNCharacterStream(String columnLabel, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+		
+	}
+
+	//## JDBC4.0-begin ##
+	public void updateNClob(int columnIndex, NClob clob) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void updateNClob(int columnIndex, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	//## JDBC4.0-begin ##
+	public void updateNClob(String columnLabel, NClob clob) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void updateNClob(String columnLabel, Reader reader, long length)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateNClob(String columnLabel, Reader reader)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateNString(int columnIndex, String string)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateNString(String columnLabel, String string)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateNull(int columnIndex) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateNull(String columnLabel) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateObject(int columnIndex, Object x, int scaleOrLength)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateObject(int columnIndex, Object x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateObject(String columnLabel, Object x, int scaleOrLength)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateObject(String columnLabel, Object x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateRef(int columnIndex, Ref x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateRef(String columnLabel, Ref x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateRow() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	//## JDBC4.0-begin ##
+	public void updateRowId(int columnIndex, RowId x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	//## JDBC4.0-begin ##
+	public void updateRowId(String columnLabel, RowId x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+	//## JDBC4.0-end ##
+
+	public void updateShort(int columnIndex, short x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateShort(String columnLabel, short x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateSQLXML(int columnIndex, SQLXML xmlObject)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateSQLXML(String columnLabel, SQLXML xmlObject)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();
+	}
+
+	public void updateString(int columnIndex, String x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateString(String columnLabel, String x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateTime(int columnIndex, Time x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateTime(String columnLabel, Time x) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateTimestamp(int columnIndex, Timestamp x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void updateTimestamp(String columnLabel, Timestamp x)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import org.teiid.client.metadata.ResultsMetadataConstants;
+
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+
+/**
+ */
+public class ResultSetMetaDataImpl extends WrapperImpl implements ResultSetMetaData {
+
+    private MetadataProvider provider;
+    
+    public ResultSetMetaDataImpl(MetadataProvider provider) {
+    	this.provider = provider;
+    }
+    
+    /**
+     * Adjust from 1-based to internal 0-based representation
+     * @param index External 1-based representation
+     * @return Internal 0-based representation
+     */
+    private int adjustColumn(int index) {
+        return index-1;
+    }
+    
+    public String getVirtualDatabaseName(int index) throws SQLException {
+        return provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.VIRTUAL_DATABASE_NAME);
+    }
+
+    public String getVirtualDatabaseVersion(int index) throws SQLException {
+        return provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.VIRTUAL_DATABASE_VERSION);
+    }
+
+    public int getColumnCount() throws SQLException {
+        return provider.getColumnCount();
+    }
+
+    public boolean isAutoIncrement(int index) throws SQLException {
+        return provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.AUTO_INCREMENTING);
+    }
+
+    public boolean isCaseSensitive(int index) throws SQLException {
+        return provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.CASE_SENSITIVE);
+    }
+
+    public boolean isSearchable(int index) throws SQLException {
+        Integer searchable = (Integer) provider.getValue(adjustColumn(index), ResultsMetadataConstants.SEARCHABLE);
+        return !(ResultsMetadataConstants.SEARCH_TYPES.UNSEARCHABLE.equals(searchable));
+    }
+
+    public boolean isCurrency(int index) throws SQLException {
+        return provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.CURRENCY);
+    }
+
+    public int isNullable(int index) throws SQLException {
+        Object nullable = provider.getValue(adjustColumn(index), ResultsMetadataConstants.NULLABLE);
+        if(nullable.equals(ResultsMetadataConstants.NULL_TYPES.NULLABLE)) {
+            return columnNullable;    
+        } else if(nullable.equals(ResultsMetadataConstants.NULL_TYPES.NOT_NULL)) {
+            return columnNoNulls;
+        } else {
+            return columnNullableUnknown;
+        }
+    }
+                        
+    public boolean isSigned(int index) throws SQLException {
+        return provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.SIGNED);
+    }
+
+    public int getColumnDisplaySize(int index) throws SQLException {
+        return provider.getIntValue(adjustColumn(index), ResultsMetadataConstants.DISPLAY_SIZE);
+    }
+
+    public String getColumnLabel(int index) throws SQLException {
+        return provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.ELEMENT_LABEL);
+    }
+
+    public String getColumnName(int index) throws SQLException {
+        return provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.ELEMENT_NAME);
+    }
+
+    public String getSchemaName(int index) throws SQLException {
+        String name = provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.GROUP_NAME);
+        if (name != null) {
+        	int dotIndex = name.indexOf('.');
+        	if (dotIndex != -1) {
+        		return name.substring(0, dotIndex);
+        	}
+        }
+        return null;
+    }
+
+    public int getPrecision(int index) throws SQLException {
+        return provider.getIntValue(adjustColumn(index), ResultsMetadataConstants.PRECISION);
+    }
+
+    public int getScale(int index) throws SQLException {
+        return provider.getIntValue(adjustColumn(index), ResultsMetadataConstants.SCALE);
+    }
+
+    public String getTableName(int index) throws SQLException {
+        String name = provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.GROUP_NAME);
+        if (name != null) {
+        	int dotIndex = name.indexOf('.');
+        	if (dotIndex != -1) {
+        		return name.substring(dotIndex + 1);
+        	}
+        }
+        return name;
+    }
+
+    public String getCatalogName(int index) throws SQLException {
+    	return provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.VIRTUAL_DATABASE_NAME);
+    }
+
+    public int getColumnType(int index) throws SQLException {
+        String runtimeTypeName = provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.DATA_TYPE);
+        return MMJDBCSQLTypeInfo.getSQLType(runtimeTypeName);
+    }
+
+    public String getColumnTypeName(int index) throws SQLException {
+        return provider.getStringValue(adjustColumn(index), ResultsMetadataConstants.DATA_TYPE);
+    }
+
+    public boolean isReadOnly(int index) throws SQLException {
+        return ! provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.WRITABLE);
+    }
+
+    public boolean isWritable(int index) throws SQLException {
+        return provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.WRITABLE);
+    }
+
+    public boolean isDefinitelyWritable(int index) throws SQLException {
+        return provider.getBooleanValue(adjustColumn(index), ResultsMetadataConstants.WRITABLE);
+    }
+
+    public String getColumnClassName(int index) throws SQLException {
+        return MMJDBCSQLTypeInfo.getJavaClassName(getColumnType(index));
+    }
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/SQLStates.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,151 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+/** 
+ * Utility class containing 1) SQL state constants used to represent JDBC error state code, and
+ * 2) utility methods to check whether a SQL state belongs to a particular class of exception states.
+ * @since 4.3
+ */
+public class SQLStates {
+	// Class 80 - connection exception
+
+	/**
+	 * Identifies the SQLState class Connection Exception (08).
+	 */
+	public static final SQLStateClass CLASS_CONNECTION_EXCEPTION = new SQLStateClass(
+			"08"); //$NON-NLS-1$
+
+	/**
+	 * Connection Exception with no subclass (SQL-99 08000)
+	 */
+	public static final String CONNECTION_EXCEPTION_NO_SUBCLASS = "08000"; //$NON-NLS-1$
+
+	/**
+	 * SQL-client unable to establish SQL-connection (SQL-99 08001)
+	 */
+	public static final String CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION = "08001"; //$NON-NLS-1$
+
+	/**
+	 * Connection name in use (SQL-99 08002)
+	 */
+	public static final String CONNECTION_EXCEPTION_CONNECTION_NAME_IN_USE = "08002"; //$NON-NLS-1$
+
+	/**
+	 * Connection does not exist (SQL-99 08003)
+	 */
+	public static final String CONNECTION_EXCEPTION_CONNECTION_DOES_NOT_EXIST = "08003"; //$NON-NLS-1$
+
+	/**
+	 * SQL-server rejected establishment of SQL-connection (SQL-99 08004)
+	 */
+	public static final String CONNECTION_EXCEPTION_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION = "08004"; //$NON-NLS-1$
+
+	/**
+	 * Connection failure (SQL-99 08006)
+	 */
+	public static final String CONNECTION_EXCEPTION_CONNECTION_FAILURE = "08006"; //$NON-NLS-1$
+
+	/**
+	 * Transaction resolution unknown (SQL-99 08007)
+	 */
+	public static final String CONNECTION_EXCEPTION_TRANSACTION_RESOLUTION_UNKNOWN = "08007"; //$NON-NLS-1$
+
+	/**
+	 * Connection is stale and should no longer be used. (08S01)
+	 * <p>
+	 * The SQLState subclass S01 is an implementation-specified condition and
+	 * conforms to the subclass DataDirect uses for SocketExceptions.
+	 */
+	public static final String CONNECTION_EXCEPTION_STALE_CONNECTION = "08S01"; //$NON-NLS-1$
+
+	// Class 28 - invalid authorization specification
+
+	/**
+	 * Identifies the SQLState class Invalid Authorization Specification (28).
+	 */
+	public static final SQLStateClass CLASS_INVALID_AUTHORIZATION_SPECIFICATION = new SQLStateClass(
+			"28"); //$NON-NLS-1$
+
+	/**
+	 * Invalid authorization specification with no subclass (SQL-99 28000)
+	 */
+	public static final String INVALID_AUTHORIZATION_SPECIFICATION_NO_SUBCLASS = "28000"; //$NON-NLS-1$
+	
+	
+	// Class 38 - External Routine Exception (as defined by SQL spec):
+    /** External routine exception. This is the default unknown code */
+    public static final String DEFAULT = "38000"; //$NON-NLS-1$
+    
+    public static final String SUCESS = "00000"; //$NON-NLS-1$
+
+    // Class 50 - Query execution errors
+    public static final SQLStateClass CLASS_USAGE_ERROR = new SQLStateClass("50"); //$NON-NLS-1$
+    /** General query execution error*/
+    public static final String USAGE_ERROR = "50000"; //$NON-NLS-1$
+    /** Error raised by ERROR instruction in virtual procedure.*/
+    public static final String VIRTUAL_PROCEDURE_ERROR = "50001"; //$NON-NLS-1$
+    
+    private static final SQLStateClass[] stateClasses = {CLASS_USAGE_ERROR};
+    static {
+        CLASS_USAGE_ERROR.stateCodes.add(USAGE_ERROR);
+        CLASS_USAGE_ERROR.stateCodes.add(VIRTUAL_PROCEDURE_ERROR);
+    }
+
+    public static boolean isSystemErrorState(String sqlStateCode) {
+        return !isUsageErrorState(sqlStateCode);
+    }
+    
+    public static boolean isUsageErrorState(String sqlStateCode) {
+        return belongsToClass(sqlStateCode, CLASS_USAGE_ERROR);
+    }
+    
+    public static boolean belongsToClass(String sqlStateCode, SQLStateClass sqlStateClass) {
+        return sqlStateCode.startsWith(sqlStateClass.codeBeginsWith);
+    }
+    
+    public static SQLStateClass getClass(String sqlStateCode) {
+        for (int i = 0; i < stateClasses.length; i++) {
+            if (stateClasses[i].containsSQLState(sqlStateCode)) {
+                return stateClasses[i];
+            }
+        }
+        return null;
+    }
+    
+    public static final class SQLStateClass {
+        private String codeBeginsWith;
+        private Set stateCodes = new HashSet();
+        private SQLStateClass(String beginsWith) {
+            this.codeBeginsWith = beginsWith;
+        }
+        
+        public boolean containsSQLState(String sqlState) {
+            return stateCodes.contains(sqlState);
+        }
+    }
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/SocketProfile.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,158 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+import org.teiid.net.TeiidURL;
+import org.teiid.net.ServerConnection;
+import org.teiid.net.socket.SocketServerConnectionFactory;
+
+import com.metamatrix.common.util.PropertiesUtils;
+import com.metamatrix.core.MetaMatrixCoreException;
+
+/**
+ * <p> The java.sql.DriverManager class uses this class to connect to Teiid Server or Teiid Embedded.
+ * The TeiidDriver class has a static initializer, which
+ * is used to instantiate and register itself with java.sql.DriverManager. The
+ * DriverManager's <code>getConnection</code> method calls <code>connect</code>
+ * method on available registered drivers. </p>
+ */
+
+final class SocketProfile {
+	
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+    
+    /**
+     *  Suports JDBC URLS of format
+     *  - jdbc:teiid:BQT at mm://localhost:####;version=1
+     *  - jdbc:teiid:BQT at mms://localhost:####;version=1
+     *  - jdbc:teiid:BQT at mm(s)://host1:####,host2:####,host3:####;version=1
+     */
+    
+    // This host/port pattern allows just a . or a - to be in the host part.
+    static final String HOST_PORT_PATTERN = "[\\p{Alnum}\\.\\-]+:\\d+"; //$NON-NLS-1$
+    static final String URL_PATTERN = "jdbc:(metamatrix|teiid):(\\w+)@((mm[s]?://"+HOST_PORT_PATTERN+"(,"+HOST_PORT_PATTERN+")*)[;]?){1}((.*)*)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    static Pattern urlPattern = Pattern.compile(URL_PATTERN);
+    
+    /**
+     * This method tries to make a connection to the given URL. This class
+     * will return a null if this is not the right driver to connect to the given URL.
+     * @param The URL used to establish a connection.
+     * @return Connection object created
+     * @throws SQLException if it is unable to establish a connection to the server.
+     */
+    public static Connection connect(String url, Properties info) throws SQLException {
+
+        ConnectionImpl myConnection = null;
+        // create a properties obj if it is null
+        if(info == null) {
+            info = new Properties();
+        } else {
+            info = PropertiesUtils.clone(info);
+        }
+
+        try {
+            // parse the URL to add it's properties to properties object
+            parseURL(url, info);
+
+            myConnection = createConnection(url, info);
+        } catch (MetaMatrixCoreException e) {
+            logger.log(Level.SEVERE, "Could not create connection", e); //$NON-NLS-1$
+            throw TeiidSQLException.create(e, e.getMessage());
+        }
+
+        // logging
+        String logMsg = JDBCPlugin.Util.getString("JDBCDriver.Connection_sucess"); //$NON-NLS-1$
+        logger.fine(logMsg);
+
+        return myConnection;
+    }
+
+    static ConnectionImpl createConnection(String url, Properties info)
+        throws ConnectionException, CommunicationException {
+
+        ServerConnection serverConn = SocketServerConnectionFactory.getInstance().getConnection(info);
+
+        // construct a MMConnection object.
+        ConnectionImpl connection = new ConnectionImpl(serverConn, info, url);
+        return connection;
+    }
+
+    /**
+     * This method parses the URL and adds properties to the the properties object.
+     * These include required and any optional properties specified in the URL.
+     * @param The URL needed to be parsed.
+     * @param The properties object which is to be updated with properties in the URL.
+     * @throws SQLException if the URL is not in the expected format.
+     */
+    protected static void parseURL(String url, Properties info) throws SQLException {
+        if(url == null) {
+            String msg = JDBCPlugin.Util.getString("MMDriver.urlFormat"); //$NON-NLS-1$
+            throw new TeiidSQLException(msg);
+        }
+        try {
+            JDBCURL jdbcURL = new JDBCURL(url);
+            info.setProperty(BaseDataSource.VDB_NAME, jdbcURL.getVDBName());
+            info.setProperty(TeiidURL.CONNECTION.SERVER_URL, jdbcURL.getConnectionURL());
+            Properties optionalParams = jdbcURL.getProperties();
+            JDBCURL.normalizeProperties(info);
+            Enumeration keys = optionalParams.keys();
+            while (keys.hasMoreElements()) {
+                String propName = (String)keys.nextElement();
+                // Don't let the URL properties override the passed-in Properties object.
+                if (!info.containsKey(propName)) {
+                    info.setProperty(propName, optionalParams.getProperty(propName));
+                }
+            }
+            // add the property only if it is new because they could have
+            // already been specified either through url or otherwise.
+            if(!info.containsKey(BaseDataSource.VDB_VERSION) && jdbcURL.getVDBVersion() != null) {
+                info.setProperty(BaseDataSource.VDB_VERSION, jdbcURL.getVDBVersion());
+            }
+            if(!info.containsKey(BaseDataSource.APP_NAME)) {
+                info.setProperty(BaseDataSource.APP_NAME, BaseDataSource.DEFAULT_APP_NAME);
+            }
+
+        } catch(IllegalArgumentException iae) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMDriver.urlFormat")); //$NON-NLS-1$
+        }  
+    }
+    
+
+    public static boolean acceptsURL(String url) {
+        Matcher m = urlPattern.matcher(url);
+        return m.matches();
+    }
+}
+
+


Property changes on: trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/StatementImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,1042 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.metadata.ParameterInfo;
+import org.teiid.client.plan.Annotation;
+import org.teiid.client.plan.PlanNode;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.core.util.ObjectConverterUtil;
+
+public class StatementImpl extends WrapperImpl implements TeiidStatement {
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+
+    // State constants
+    protected static final int TIMED_OUT = 4;
+    protected static final int CANCELLED = 3;
+    protected static final int NO_TIMEOUT = 0;
+
+    // integer indicating no maximum limit - used in some metadata-ish methods.
+    private static final int NO_LIMIT = 0;
+
+    //######## Configuration state #############
+    private ConnectionImpl driverConnection;
+    private Properties execProps = null;
+
+    // the string which is the XSLT style sheet
+    private String styleSheet;
+
+    // fetch size value. This is the default fetch size used by the server
+    private int fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+
+    // the fetch direction
+    private int fetchDirection = ResultSet.FETCH_FORWARD;
+
+    // the result set type
+    private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
+    private int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;
+
+    //######## Processing state #############
+
+    // boolean to indicate if this statement object is closed
+    private boolean isClosed = false;
+
+    // Differentiate timeout from cancel in blocking asynch operation
+    protected int commandStatus = -1;
+
+    // number of seconds for the query to timeout.
+    protected int queryTimeout = NO_TIMEOUT;
+
+    //########## Per-execution state ########
+
+    // ID for current request
+    protected long currentRequestID = -1;
+
+    //  the last query plan description
+    private Map currentPlanDescription;
+
+    // the last query debug log
+    private String debugLog;
+
+    // the last query annotations
+    private List<Annotation> annotations;
+
+    // resultSet object produced by execute methods on the statement.
+    protected ResultSetImpl resultSet;
+
+    private List<Exception> serverWarnings;
+
+    // the per-execution security payload
+    private Serializable payload;
+    
+    /** List of INSERT, UPDATE, DELETE AND SELECT INTO commands */
+    private List batchedUpdates;
+    
+    /** Array of update counts as returned by executeBatch() */
+    protected int[] updateCounts;
+    
+    /** default Calendar instance for converting date/time/timestamp values */
+    private Calendar defaultCalendar;
+    /** Max rows to be returned by executing the statement */
+    private int maxRows = NO_LIMIT;
+    private int maxFieldSize = NO_LIMIT;
+    
+    /** SPIN_TIMEOUT determines how responsive asynch operations will be to
+     *  statement cancellation, closure, or execution timeouts.  
+     *  1/2 second was chosen as default.
+     */
+    private static int SPIN_TIMEOUT = 500;
+    
+    //Map<out/inout/return param index --> index in results>
+    protected Map outParamIndexMap = new HashMap();
+    
+    private Pattern setStatement = Pattern.compile("\\s*set\\s*(\\w+)\\s*=\\s*(\\w*)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+    
+    /**
+     * Factory Constructor 
+     * @param driverConnection
+     * @param resultSetType
+     * @param resultSetConcurrency
+     */
+    static StatementImpl newInstance(ConnectionImpl driverConnection, int resultSetType, int resultSetConcurrency) {
+        return new StatementImpl(driverConnection, resultSetType, resultSetConcurrency);        
+    }
+    
+    /**
+     * MMStatement Constructor.
+     * @param driverConnection
+     * @param resultSetType
+     * @param resultSetConcurrency
+     */
+    StatementImpl(ConnectionImpl driverConnection, int resultSetType, int resultSetConcurrency) {
+        this.driverConnection = driverConnection;
+        this.resultSetType = resultSetType;
+        this.resultSetConcurrency = resultSetConcurrency;
+        this.execProps = new Properties(this.driverConnection.getConnectionProperties());
+        
+        // Set initial fetch size
+        String fetchSizeStr = this.execProps.getProperty(ExecutionProperties.PROP_FETCH_SIZE);
+        if(fetchSizeStr != null) {
+            try {
+                this.fetchSize = Integer.parseInt(fetchSizeStr);
+            } catch(Exception e) {
+                // silently failover to default
+            }
+        }        
+    }
+
+    protected DQP getDQP() {
+    	return this.driverConnection.getDQP();
+    }
+    
+    protected ConnectionImpl getMMConnection() {
+    	return this.driverConnection;
+    }
+    
+    protected TimeZone getServerTimeZone() throws SQLException {
+    	return this.driverConnection.getServerConnection().getLogonResult().getTimeZone();
+    }
+        
+    /**
+     * Reset all per-execution state - this should be done before executing
+     * a new command.
+     */
+    protected void resetExecutionState() throws SQLException {
+        this.currentRequestID = -1;
+
+        this.currentPlanDescription = null;
+        this.debugLog = null;
+        this.annotations = null;
+
+        if ( this.resultSet != null ) {
+            this.resultSet.close();
+            this.resultSet = null;
+        }
+
+        this.serverWarnings = null;
+        
+        this.batchedUpdates = null;
+        this.updateCounts = null;
+        this.outParamIndexMap.clear();
+    }
+
+    /**
+     * Adds sql to this statement object's current list of commands.
+     * @param sql statement to be added to the batch
+     */
+    public void addBatch(String sql) throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        if (batchedUpdates == null) {
+            batchedUpdates = new ArrayList();
+        }
+        batchedUpdates.add(sql);
+    }
+
+    /**
+     * This method can be used by one thread to cancel a statement that is being
+     * executed by another thread.
+     * @throws SQLException should never occur.
+     */
+    public void cancel() throws SQLException {
+        /* Defect 19848 - Mark the statement cancelled before sending the CANCEL request.
+         * Otherwise, it's possible get into a race where the server response is quicker
+         * than the exception in the exception in the conditionalWait(), which results in
+         * the statement.executeQuery() call throwing the server's exception instead of the
+         * one generated by the conditionalWait() method.
+         */
+        commandStatus = CANCELLED;
+        cancelRequest();
+    }
+
+    /**
+     * Warning could be schema validation errors or partial results warnings.
+     * @throws SQLException should never occur.
+     */
+    public void clearWarnings() throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+
+        // clear all the warnings on this statement, after this, getWarnings() should return null
+        serverWarnings = null;
+    }
+
+    /**
+     * Makes the set of commands in the current batch empty.
+     *
+     * @throws SQLException if a database access error occurs or the
+     * driver does not support batch statements
+     */
+    public void clearBatch() throws SQLException {
+        batchedUpdates.clear();
+    }
+
+    /**
+     * In many cases, it is desirable to immediately release a Statements's database
+     * and JDBC resources instead of waiting for this to happen when it is automatically
+     * closed; the close method provides this immediate release.
+     * @throws SQLException should never occur.
+     */
+    public void close() throws SQLException {
+        if ( isClosed ) {
+            return;
+        }
+
+        // close the the server's statement object (if necessary)
+        if(resultSet != null) {
+            resultSet.close();
+            resultSet = null;
+        }
+
+        isClosed = true;
+
+        // Remove link from connection to statement
+        this.driverConnection.closeStatement(this);
+
+        logger.fine(JDBCPlugin.Util.getString("MMStatement.Close_stmt_success")); //$NON-NLS-1$
+        driverConnection = null;
+    }
+
+    /**
+     * <p> This utility method checks if the jdbc statement is closed and
+     * throws an exception if it is closed. </p>
+     * @throws SQLException if the statement object is closed.
+     */
+    protected void checkStatement() throws SQLException {
+        //Check to see the connection is closed and proceed if it is not
+        if ( isClosed ) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Stmt_closed")); //$NON-NLS-1$
+        }
+    }
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public boolean execute(String sql) throws SQLException {
+        executeSql(new String[] {sql}, false, ResultsMode.EITHER);
+        return hasResultSet();
+    }
+    
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public int[] executeBatch() throws SQLException {
+        if (batchedUpdates == null || batchedUpdates.isEmpty()) {
+            return new int[0];
+        }
+        String[] commands = (String[])batchedUpdates.toArray(new String[batchedUpdates.size()]);
+        executeSql(commands, true, ResultsMode.UPDATECOUNT);
+        return updateCounts;
+    }
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public ResultSet executeQuery(String sql) throws SQLException {
+        executeSql(new String[] {sql}, false, ResultsMode.RESULTSET);
+        return resultSet;
+    }
+
+	//## JDBC4.0-begin ##
+	@Override
+	//## JDBC4.0-end ##
+    public int executeUpdate(String sql) throws SQLException {
+        String[] commands = new String[] {sql};
+        executeSql(commands, false, ResultsMode.UPDATECOUNT);
+        return this.updateCounts[0];
+    }
+
+    protected boolean hasResultSet() throws SQLException {
+        return resultSet != null && resultSet.getMetaData().getColumnCount() > 0;
+    }
+    
+	protected void createResultSet(ResultsMessage resultsMsg) throws SQLException {
+		//create out/return parameter index map if there is any
+		List listOfParameters = resultsMsg.getParameters();
+		if(listOfParameters != null){
+		    //get the size of result set
+		    int resultSetSize = 0;
+		    Iterator iteratorOfParameters = listOfParameters.iterator();
+		    while(iteratorOfParameters.hasNext()){
+		        ParameterInfo parameter = (ParameterInfo)iteratorOfParameters.next();
+		        if(parameter.getType() == ParameterInfo.RESULT_SET){
+		            resultSetSize = parameter.getNumColumns();
+		            //one ResultSet only
+		            break;
+		        }
+		    }
+
+		    //return needs to be the first
+		    int index = 0; //index in user call - {?=call sp(?)}
+		    int count = 0;
+		    iteratorOfParameters = listOfParameters.iterator();
+		    while(iteratorOfParameters.hasNext()){
+		        ParameterInfo parameter = (ParameterInfo)iteratorOfParameters.next();
+		        if(parameter.getType() == ParameterInfo.RETURN_VALUE){
+		            count++;
+		            index++;
+		            outParamIndexMap.put(new Integer(index), new Integer(resultSetSize + count));
+		            break;
+		        }
+		    }
+
+		    iteratorOfParameters = listOfParameters.iterator();
+		    while(iteratorOfParameters.hasNext()){
+		        ParameterInfo parameter = (ParameterInfo)iteratorOfParameters.next();
+		        if(parameter.getType() != ParameterInfo.RETURN_VALUE && parameter.getType() != ParameterInfo.RESULT_SET){
+		            index++;
+		            if(parameter.getType() == ParameterInfo.OUT || parameter.getType() == ParameterInfo.INOUT){
+		                count++;
+		                outParamIndexMap.put(new Integer(index), new Integer(resultSetSize + count));
+		            }
+		        }
+		    }
+		}
+
+		resultSet = new ResultSetImpl(resultsMsg, this, null, outParamIndexMap.size());
+		resultSet.setMaxFieldSize(this.maxFieldSize);
+	}
+    
+    protected void executeSql(String[] commands, boolean isBatchedCommand, ResultsMode resultsMode)
+        throws SQLException, TeiidSQLException {
+        checkStatement();
+        resetExecutionState();
+        
+        //handle set statement
+        if (commands.length == 1 && resultsMode != ResultsMode.RESULTSET) {
+        	Matcher match = setStatement.matcher(commands[0]);
+        	if (match.matches()) {
+        		String key = match.group(1);
+        		String value = match.group(2);
+        		this.driverConnection.getConnectionProperties().setProperty(key, value);
+        		this.updateCounts = new int[] {0};
+        		return;
+        	}
+        }
+        
+        RequestMessage reqMessage = createRequestMessage(commands, isBatchedCommand, resultsMode);
+    	ResultsMessage resultsMsg = null;
+        try {
+        	resultsMsg = sendRequestMessageAndWait(reqMessage);
+        } catch ( Throwable ex ) {
+            String msg = JDBCPlugin.Util.getString("MMStatement.Error_executing_stmt", reqMessage.getCommandString()); //$NON-NLS-1$ 
+            logger.log(Level.SEVERE, msg, ex);
+            throw TeiidSQLException.create(ex, msg);
+        }
+        
+        // warnings thrown
+        List resultsWarning = resultsMsg.getWarnings();
+
+        setAnalysisInfo(resultsMsg);
+
+        if (resultsMsg.getException() != null) {
+            throw TeiidSQLException.create(resultsMsg.getException());
+        }
+
+        // save warnings if have any
+        if (resultsWarning != null) {
+            accumulateWarnings(resultsWarning);
+        }
+        
+        if (resultsMsg.isUpdateResult()) {
+        	List[] results = resultsMsg.getResults();
+        	this.updateCounts = new int[results.length];
+            for (int i = 0; i < results.length; i++) {
+            	updateCounts[i] = (Integer)results[i].get(0);
+            }
+            
+            // In update scenarios close the statement implicitly
+            try {
+				getDQP().closeRequest(getCurrentRequestID());
+			} catch (MetaMatrixProcessingException e) {
+				throw TeiidSQLException.create(e);
+			} catch (MetaMatrixComponentException e) {
+				throw TeiidSQLException.create(e);
+			}            
+        } else {
+            createResultSet(resultsMsg);
+        }
+        
+        logger.fine(JDBCPlugin.Util.getString("MMStatement.Success_query", reqMessage.getCommandString())); //$NON-NLS-1$
+    }
+
+	protected RequestMessage createRequestMessage(String[] commands,
+			boolean isBatchedCommand, ResultsMode resultsMode) {
+        RequestMessage reqMessage = new RequestMessage();
+    	reqMessage.setCommands(commands);
+    	reqMessage.setBatchedUpdate(isBatchedCommand);
+    	reqMessage.setResultsMode(resultsMode);
+		return reqMessage;
+	}
+
+    /**
+     * Retreives the fetch direction this Statement object set as a performance hint
+     * to the driver. The int returned will be one of the following constants from
+     * the ResultSet interface: FETCH_FORWARD, FETCH_REVERSE, or FETCH_UNKNOWN.
+     * @return int value indicating the direction in which results need to be fetched
+     * @throws SQLException should never occur.
+     */
+    public int getFetchDirection() throws SQLException {
+        return this.fetchDirection;
+    }
+
+    /**
+     * Retreives the fetch size this Statement object set as a performance hint
+     * to the driver. This is the number of rows the server fetches at a time when
+     * the result set needs more rows.
+     * @return int value indicating the number of rows the server fetches
+     * @throws SQLException should never occur.
+     */
+    public int getFetchSize() throws SQLException {
+        return fetchSize;
+    }
+
+    /**
+     * Retreives the maximum number of bytes that a result set column may contain.
+     * @return int value giving the maximum size of a field
+     * @throws SQLException should never occur.
+     */
+    public int getMaxFieldSize() throws SQLException {
+        return maxFieldSize;
+    }
+
+    /**
+     * Retrives the maximum number of rows that a ResultSet object may contain.
+     * If the limit is exceeded the excess rows are dropped.
+     * @return Max limit on rows on ResultSet.
+     * @throws SQLException should never iccure.
+     */
+    public int getMaxRows() throws SQLException {
+        return maxRows;
+    }
+
+    /**
+     * Moves to this Statement object's next result, returns true if
+     * it is a ResultSet object, and implicitly closes any current
+     * ResultSet object(s) obtained with the method #getResultSet.
+     * @return true if the next result is a ResultSet object;
+     * false if it is an update count or there are no more results
+     * @throws SQLException if there is an error in database.
+     */
+    public boolean getMoreResults() throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+
+        // close any current ResultSet
+        if ( resultSet != null ) {
+            resultSet.close();
+            resultSet = null;
+        }
+        // set the existing update count to -1
+        // indicating that there are no more results
+        this.updateCounts = null;
+        return false;
+    }
+
+    /**
+     * Moves to this Statement object's next result, deals with any current
+     * ResultSet object(s) according to the instructions specified by the
+     * given flag, and returns true if the next result is a ResultSet object.
+     * @param current flag that gives instruction on what should happen
+     * to current ResultSet objects obtained using the method getResultSet(
+     * CLOSE_CURRENT_RESULT, KEEP_CURRENT_RESULT, or CLOSE_ALL_RESULTS).
+     * @return true if the next result is a ResultSet object; false if it
+     *  is an update count or there are no more results
+     * @throws SQLException if there is an error in database.
+     */
+    public boolean getMoreResults(int current) throws SQLException {
+        checkStatement();
+
+        /*if (current == CLOSE_ALL_RESULTS || current == CLOSE_CURRENT_RESULT) {
+            // since MetaMatrix only supports one ResultSet per statement,
+            // these two cases are handled the same way.
+            if (resultSet != null) {
+                resultSet.close();
+            }
+        } else if (current == KEEP_CURRENT_RESULT) {
+            // do nothing
+        }
+
+        rowsAffected = -1;
+        */
+        return false;
+    }
+
+
+    /**
+     * Return the number of seconds the driver will wait for a statement object
+     * to execute
+     * @return int value giving the query timeout in seconds
+     * @throws SQLException should never occur
+     */
+    public int getQueryTimeout() throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        return this.queryTimeout;
+    }
+
+    /**
+     * Returns a ResultSet object that was produced by a call to the method execute.
+     * We currently do not support execute method which could return multiple result
+     * sets.
+     * @return ResultSet object giving the next available ResultSet
+     * @throws SQLException should never occur
+     */
+    public ResultSet getResultSet() throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        if (!hasResultSet()) {
+        	return null;
+        }
+        return resultSet;
+    }
+
+    /**
+     * Retrieves the concurrency mode for the ResultSet objects generated from
+     * queries that this Statement object executes. All ResultSets are currently
+     * read only.
+     * @return intvalue giving the ResultSet concurrency
+     * @throws SQLException should never occur
+     */
+    public int getResultSetConcurrency() throws SQLException {
+        return this.resultSetConcurrency;
+    }
+
+    /**
+     * Retrieves the type of the ResultSet objects generated from queries that this
+     * statement executes.
+     * @return int value indicating the type of the ResultSet
+     * @throws SQLException should never occur
+     */
+    public int getResultSetType() {
+        return this.resultSetType;
+    }
+
+    /**
+     * This method returns the number of rows affected by a statement modifying a table.
+     * @return Number of rows affected.
+     * @throws SQLException should never occur
+     */
+    public int getUpdateCount() throws SQLException {
+        checkStatement();
+        if (this.updateCounts == null) {
+        	return -1;
+        }
+        return this.updateCounts[0];
+    }
+
+    protected void accumulateWarnings(List<Exception> serverWarnings) {
+    	if (serverWarnings == null || serverWarnings.isEmpty()) {
+    		return;
+    	}
+    	if (this.serverWarnings == null) {
+    		this.serverWarnings = new ArrayList<Exception>();
+    	}
+    	this.serverWarnings.addAll(serverWarnings);
+    }
+
+    /**
+     * This method returns warnings returned by server.
+     * @return null value as there are no warnings
+     * @throws SQLException should never occur
+     */
+    public SQLWarning getWarnings() throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+
+        if (serverWarnings != null && serverWarnings.size() != 0) {
+            return WarningUtil.convertWarnings(serverWarnings);
+        }
+        return null;
+    }
+
+    /**
+     * This method enbles/disables escape processing. When escape processing is
+     * enabled the driver will scan any escape syntax and do escape substitution
+     * before sending the escaped sql statement to the server
+     * @param enable boolean value indicating if the escape processing should be turned on
+     * @throws SQLException should never occur
+     */
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        // do nothing, escape processing is always enabled.
+    }
+
+    public void setFetchDirection(int direction) throws SQLException {
+        checkStatement();
+    }
+
+    public void setFetchSize(int rows) throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        if ( rows < 0 ) {
+            String msg = JDBCPlugin.Util.getString("MMStatement.Invalid_fetch_size"); //$NON-NLS-1$
+            throw new TeiidSQLException(msg);
+        }
+        // sets the fetch size on this statement
+        if (rows == 0) {
+            this.fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+        } else {
+            this.fetchSize = rows;
+        }
+    }
+
+    /**
+     * Sets the limit on the maximum number of rows in a ResultSet object. This
+     * method is currently implemented to throw an exception as it is not possible
+     * to limit the number of rows.
+     * @param maxRows int value indicating maximum rows that can be returned in a ResultSet
+     */
+    public void setMaxRows(int maxRows) throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        this.maxRows = maxRows;
+    }
+
+    /**
+     * This sets to seconds the time limit for the number of seconds for a driver
+     * to wait for a statement object to be executed.
+     * @param seconds Maximum number of seconds for a statement object to execute.
+     * throws SQLException, should never occur
+     */
+    public void setQueryTimeout(int seconds) throws SQLException {
+        //Check to see the statement is closed and throw an exception
+        checkStatement();
+        if (seconds >= 0) {
+            queryTimeout = seconds;
+        }
+        else {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Bad_timeout_value")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Helper method for copy the connection properties to request message.
+     * @param res Request message that these properties to be copied to.
+     * @throws TeiidSQLException 
+     */
+    protected void copyPropertiesToRequest(RequestMessage res) throws TeiidSQLException {
+        // Get partial mode
+        String partial = getExecutionProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE);
+        res.setPartialResults(Boolean.valueOf(partial).booleanValue());
+
+        // Get xml validation mode
+        String validate = getExecutionProperty(ExecutionProperties.PROP_XML_VALIDATION);
+        if(validate == null) {
+            res.setValidationMode(false);
+        } else {
+            res.setValidationMode(Boolean.valueOf(validate).booleanValue());
+        }
+
+        // Get xml format mode
+        String format = getExecutionProperty(ExecutionProperties.PROP_XML_FORMAT);
+        res.setXMLFormat(format);
+
+        // Get transaction auto-wrap mode
+        String txnAutoWrapMode = getExecutionProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP);
+        try {
+			res.setTxnAutoWrapMode(txnAutoWrapMode);
+		} catch (MetaMatrixProcessingException e) {
+			throw TeiidSQLException.create(e);
+		}
+        
+        // Get result set cache mode
+        String rsCache = getExecutionProperty(ExecutionProperties.RESULT_SET_CACHE_MODE);
+        res.setUseResultSetCache(Boolean.valueOf(rsCache).booleanValue());
+        
+        res.setAnsiQuotedIdentifiers(Boolean.valueOf(
+                getExecutionProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS))
+                .booleanValue());
+        String sqlOptions = getExecutionProperty(ExecutionProperties.PROP_SQL_OPTIONS);
+        if (sqlOptions != null &&
+            sqlOptions.toUpperCase().indexOf(ExecutionProperties.SQL_OPTION_SHOWPLAN.toUpperCase()) >= 0) {
+            res.setShowPlan(true);
+        }
+    }
+
+    /**
+     * Ends the command and sets the status to TIMED_OUT.
+     */
+    protected void timeoutOccurred() {
+        logger.warning(JDBCPlugin.Util.getString("MMStatement.Timeout_ocurred_in_Statement.")); //$NON-NLS-1$
+        try {
+        	cancel();        
+            commandStatus = TIMED_OUT;
+            queryTimeout = NO_TIMEOUT;
+            currentRequestID = -1;
+            if (this.resultSet != null) {
+                this.resultSet.close();
+            }
+        } catch (SQLException se) {
+            logger.log(Level.SEVERE, JDBCPlugin.Util.getString("MMStatement.Error_timing_out."), se); //$NON-NLS-1$
+        }
+    }
+
+    protected void cancelRequest() throws SQLException {
+        checkStatement();
+
+        try {
+			this.getDQP().cancelRequest(currentRequestID);
+		} catch (MetaMatrixProcessingException e) {
+			throw TeiidSQLException.create(e);
+		} catch (MetaMatrixComponentException e) {
+			throw TeiidSQLException.create(e);
+		}
+    }
+
+    /**
+     * Set the per-statement security payload.  This optional payload will 
+     * accompany each request to the data source(s) so that the connector
+     * will have access to it.
+     * <br>Once the payload is set, it will be used for each statment
+     * execution until it is set to <code>null</code>, a new payload is set on
+     * the statement or the statement is closed.</br>
+     * 
+     * <p>To remove an existing payload from a statement, call this method
+     * with a <code>null</code> argument.</p>  
+     * @param payload The payload that is to accompany requests executed
+     * from this statement.
+     * @since 4.2
+     */
+    public void setPayload(Serializable payload) {
+        this.payload = payload;
+    }
+
+    public void setExecutionProperty(String name, String value) {
+        this.execProps.put(name, value);
+    }
+
+    public String getExecutionProperty(String name) {
+        return (String) this.execProps.get(name);
+    }
+
+    /**
+     * Send out request message with necessary states.
+     */
+    protected ResultsMessage sendRequestMessageAndWait(RequestMessage reqMsg)
+        throws SQLException, InterruptedException, TimeoutException {
+        this.currentRequestID = this.driverConnection.nextRequestID();
+        // Create a request message
+        reqMsg.setExecutionPayload(this.payload);        
+        reqMsg.setCursorType(this.resultSetType);
+        reqMsg.setFetchSize(this.fetchSize);
+        reqMsg.setStyleSheet(this.styleSheet);
+        reqMsg.setRowLimit(this.maxRows);
+        reqMsg.setTransactionIsolation(this.driverConnection.getTransactionIsolation());
+
+        // Get connection properties and set them onto request message
+        copyPropertiesToRequest(reqMsg);
+
+        reqMsg.setExecutionId(this.currentRequestID);
+    	
+        Future<ResultsMessage> pendingResult = null;
+		try {
+			pendingResult = this.getDQP().executeRequest(this.currentRequestID, reqMsg);
+		} catch (MetaMatrixException e) {
+			throw TeiidSQLException.create(e);
+		}
+		long timeoutMillis = queryTimeout * 1000;
+        long endTime = System.currentTimeMillis() + timeoutMillis;
+        ResultsMessage result = null;        
+        while (result == null) {
+
+        	if (timeoutMillis > 0 && endTime <= System.currentTimeMillis() && commandStatus != TIMED_OUT && commandStatus != CANCELLED) {
+	            timeoutOccurred();
+        	}
+        	
+            checkStatement();
+			try {
+				result = pendingResult.get(SPIN_TIMEOUT, TimeUnit.MILLISECONDS);
+			} catch (ExecutionException e) {
+				throw TeiidSQLException.create(e);
+			} catch (TimeoutException e) {
+				continue;
+			}
+        }
+        
+    	if (commandStatus == CANCELLED) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Cancel_before_execute")); //$NON-NLS-1$
+        }
+    	 
+    	if (commandStatus == TIMED_OUT) {
+            throw new TimeoutException(JDBCPlugin.Util.getString("MMStatement.Timeout_before_complete")); //$NON-NLS-1$
+        }    	
+    	return result;
+    }
+
+    long getCurrentRequestID() {
+        return this.currentRequestID;
+    }
+
+    /**
+     * <p> This method sets a style sheet to this object. The style sheet is
+     * to perform transformations.
+     * @param reader The reader object from which the styleSheet is to be read
+     * @throws IOException if unable to read the style sheet from the Reader object.
+     */
+    public void attachStylesheet(Reader reader) throws IOException {
+        this.styleSheet = ObjectConverterUtil.convertToString(reader);
+    }
+
+    /**
+     * <p> This method removes any existing style sheet on this object.
+     */
+    public void clearStylesheet() {
+        this.styleSheet = null;
+    }
+
+    void setPlanDescription(Map planDescription) {
+        this.currentPlanDescription = planDescription;
+    }
+
+    void setDebugLog(String debugLog) {
+        this.debugLog = debugLog;
+    }
+
+    void setAnnotations(List<Annotation> annotations) {
+        this.annotations = annotations;
+    }
+
+    /**
+     * Get Query plan description.
+     * If the Statement has a resultSet, we get the plan description from the result set
+     * If that plan description is null, though, we return the very first plan description
+     * that was created from the resultsMessage in the method: setAnalysisInfo.
+     * The plan description from the result set can be null if the resultsMsg stored in the
+     * result set hasn't been created when getPlanDescription is called.
+     * @return Query plan description, if it exists, otherwise null
+     */
+    public PlanNode getPlanDescription() {
+        Map planDescription = null;
+        if(this.resultSet != null) {
+			planDescription = this.resultSet.getUpdatedPlanDescription();
+        }
+        if(planDescription != null) {
+            this.currentPlanDescription = planDescription;
+            return PlanNode.constructFromMap(this.currentPlanDescription);
+        }else if(this.currentPlanDescription != null) {
+            return PlanNode.constructFromMap(this.currentPlanDescription);
+        }
+        return null;
+    }
+
+    /**
+     * Get query planner debug log.
+     * @return Query planner debug log, or null if it doesn't exist
+     */
+    public String getDebugLog() {
+        return this.debugLog;
+    }
+
+    /**
+     * Get annotations
+     * @return Query planner annotations - Collection of Annotation
+     */
+    public Collection<Annotation> getAnnotations() {
+        return this.annotations;
+    }
+    
+    public void setPartialResults(boolean isPartialResults){
+        if(isPartialResults){
+            this.execProps.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, "true"); //$NON-NLS-1$
+        }
+    }
+
+    public String getRequestIdentifier() {
+        if(this.currentRequestID >= 0) {
+            return Long.toString(this.currentRequestID);
+        }
+        return null;
+    }
+    
+    /**
+     * Check is the statement is closed. Used primarily by the unit tests.
+     * @return true if the statement is closed; false otherwise.
+     */
+    public boolean isClosed() {
+        return this.isClosed;
+    }
+
+	protected void setAnalysisInfo(ResultsMessage resultsMsg) {
+        this.debugLog = resultsMsg.getDebugLog();
+        this.currentPlanDescription = resultsMsg.getPlanDescription();
+        Collection serverAnnotations = resultsMsg.getAnnotations();
+        if(serverAnnotations != null) {
+            List<Annotation> annotations = new ArrayList<Annotation>(serverAnnotations.size());
+            Iterator annIter = serverAnnotations.iterator();
+            while(annIter.hasNext()) {
+                String[] serverAnnotation = (String[]) annIter.next();
+                Annotation annotation = new Annotation(serverAnnotation);
+                annotations.add(annotation);                
+            }
+            this.annotations = annotations;            
+        }
+	}
+    
+    Calendar getDefaultCalendar() {
+        if (defaultCalendar == null) {
+            defaultCalendar = Calendar.getInstance();
+        }
+        return defaultCalendar;
+    }
+    
+    void setDefaultCalendar(Calendar cal) {
+        this.defaultCalendar = cal;
+    }
+            
+	public boolean isPoolable() throws SQLException {
+		checkStatement();
+		return false;
+	}
+
+	public void setPoolable(boolean arg0) throws SQLException {
+		checkStatement();
+	}
+	
+	public Connection getConnection() throws SQLException {
+		return this.driverConnection;
+	}
+
+	public boolean execute(String sql, int autoGeneratedKeys)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public boolean execute(String sql, String[] columnNames)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public int executeUpdate(String sql, int autoGeneratedKeys)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public int executeUpdate(String sql, int[] columnIndexes)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public int executeUpdate(String sql, String[] columnNames)
+			throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public ResultSet getGeneratedKeys() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public int getResultSetHoldability() throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void setCursorName(String name) throws SQLException {
+		throw SqlUtil.createFeatureNotSupportedException();	
+	}
+
+	public void setMaxFieldSize(int max) throws SQLException {
+		checkStatement();
+        if ( max < 0 ) {
+            throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Invalid_field_size")); //$NON-NLS-1$
+        }
+		this.maxFieldSize = max;
+	}
+}
\ No newline at end of file

Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidDataSource.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,479 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.util.Properties;
+
+import org.teiid.net.TeiidURL;
+
+
+/**
+ * The Teiid JDBC DataSource implementation class of {@link javax.sql.DataSource} and
+ * {@link javax.sql.XADataSource}.
+ * <p>
+ * The {@link javax.sql.DataSource} interface follows the JavaBean design pattern,
+ * meaning the implementation class has <i>properties</i> that are accessed with getter methods
+ * and set using setter methods, and where the getter and setter methods follow the JavaBean
+ * naming convention (e.g., <code>get</code><i>PropertyName</i><code>() : </code><i>PropertyType</i>
+ * and <code>set</code><i>PropertyName</i><code>(</code><i>PropertyType</i><code>) : void</code>).
+ * </p>
+ * The {@link javax.sql.XADataSource} interface is almost identical to the {@link javax.sql.DataSource}
+ * interface, but rather than returning {@link java.sql.Connection} instances, there are methods that
+ * return {@link javax.sql.XAConnection} instances that can be used with distributed transactions.
+ * <p>
+ * The following are the properties for this DataSource:
+ * <table cellspacing="0" cellpadding="0" border="1" width="100%">
+ *   <tr><td><b>Property Name</b></td><td><b>Type</b></td><td><b>Description</b></td></tr>
+ *   <tr><td>portNumber       </td><td><code>int   </code></td><td>The port number where a Teiid Server is listening
+ *                                                                 for requests.</td></tr>
+ *   <tr><td>serverName       </td><td><code>String</code></td><td>The hostname or IP address of the Teiid Server.</td></tr>
+ * <table>
+ * If "serverName" property is not set then data source will try to create a embedded connection to the Teiid server.
+ * </p>
+ */
+public class TeiidDataSource extends BaseDataSource {
+
+	private static final long serialVersionUID = -5170316154373144878L;
+
+	/**
+     * The port number where a server is listening for requests.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>optional</i>.
+     */
+    private int portNumber;
+
+    /**
+     * The name of the host where the sServer is running.
+     * This property name is one of the standard property names defined by the JDBC 2.0 specification,
+     * and is <i>required</i>.
+     */
+    private String serverName;
+     
+    /**
+     * Specify whether to make a secure (SSL, mms:) connection or a normal non-SSL mm: connection.
+     * the default is to use a non-secure connection.
+     * @since 5.0.2
+     */
+    private boolean secure = false;
+
+    /**
+     * Holds a comma delimited list of alternate Server(s):Port(s) that can 
+     * be used for connection fail-over.
+     * @since 5.5
+     */
+    private String alternateServers;
+    
+    /**
+     * The auto failover mode for calls made to the query engine.  If true query engine calls that fail will
+     * allow the connection to choose another process.
+     */
+    private String autoFailover;
+    
+    private String discoveryStrategy;
+    
+    /**
+     * Constructor for MMDataSource.
+     */
+    public TeiidDataSource() {
+    }
+
+    // --------------------------------------------------------------------------------------------
+    //                             H E L P E R   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    protected Properties buildProperties(final String userName, final String password) {               
+        Properties props = super.buildProperties(userName, password);
+        
+        if (this.getAutoFailover() != null) {
+            props.setProperty(TeiidURL.CONNECTION.AUTO_FAILOVER, this.getAutoFailover());
+        }
+        
+        if (this.getDiscoveryStrategy() != null) {
+        	props.setProperty(TeiidURL.CONNECTION.DISCOVERY_STRATEGY, this.getDiscoveryStrategy());
+        }
+
+        return props;
+    }
+    
+    private Properties buildServerProperties(final String userName, final String password) {               
+        Properties props = buildProperties(userName, password);
+        
+        props.setProperty(TeiidURL.CONNECTION.SERVER_URL,this.buildServerURL());
+
+        return props;
+    }    
+
+    protected String buildServerURL() {
+    	if ( this.alternateServers == null ) {
+    		// Format:  "mm://server:port"
+    		return new TeiidURL(this.serverName, this.portNumber, this.secure).getAppServerURL();
+    	} 
+
+    	// Format: "mm://server1:port,server2:port,..."
+		String serverURL = ""; //$NON-NLS-1$
+		
+		serverURL = "" + ( this.secure ? TeiidURL.SECURE_PROTOCOL : TeiidURL.DEFAULT_PROTOCOL ); //$NON-NLS-1$
+		serverURL += "" + this.serverName; //$NON-NLS-1$
+		if ( this.portNumber != 0 ) 
+			serverURL += TeiidURL.COLON_DELIMITER  + this.portNumber;
+		if ( this.alternateServers.length() > 0 ) {
+        	String[] as = this.alternateServers.split( TeiidURL.COMMA_DELIMITER);
+        	
+        	for ( int i = 0; i < as.length; i++ ) {
+        		String[] server = as[i].split( TeiidURL.COLON_DELIMITER );
+
+        		if ( server.length > 0 ) {
+        			serverURL += TeiidURL.COMMA_DELIMITER + server[0];
+        			if ( server.length > 1 ) {
+        				serverURL += TeiidURL.COLON_DELIMITER + server[1];
+        			} else {
+        				serverURL += TeiidURL.COLON_DELIMITER + this.portNumber;
+        			}
+        		}
+        	}
+		}
+		
+		return new TeiidURL(serverURL).getAppServerURL();
+    }
+
+    protected String buildURL() {
+        return new JDBCURL(this.getDatabaseName(), buildServerURL(), buildProperties(getUser(), getPassword())).getJDBCURL();
+    }
+
+    protected void validateProperties( final String userName, final String password) throws java.sql.SQLException {
+        super.validateProperties(userName, password);
+        
+        String reason = reasonWhyInvalidPortNumber(this.portNumber);
+        if ( reason != null ) {
+            throw createConnectionError(reason);
+        }
+
+        reason = reasonWhyInvalidServerName(this.serverName);
+        if ( reason != null ) {
+            throw createConnectionError(reason);
+        }
+
+        reason = reasonWhyInvalidAlternateServers(this.alternateServers);
+        if ( reason != null) {
+        	throw createConnectionError(reason);
+        }
+    }
+    
+    private TeiidSQLException createConnectionError(String reason) {
+        String msg = JDBCPlugin.Util.getString("MMDataSource.Err_connecting", reason); //$NON-NLS-1$
+        return new TeiidSQLException(msg);        
+    }
+
+    // --------------------------------------------------------------------------------------------
+    //                        D A T A S O U R C E   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    /**
+     * Attempt to establish a database connection.
+     * @return a Connection to the database
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#getConnection()
+     */
+    public Connection getConnection() throws java.sql.SQLException {
+        return getConnection(null,null);
+    }
+
+    /**
+     * Attempt to establish a database connection.
+     * @param userName the database user on whose behalf the Connection is being made
+     * @param password the user's password
+     * @return a Connection to the database
+     * @throws java.sql.SQLException if a database-access error occurs
+     * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
+     */
+    public Connection getConnection(String userName, String password) throws java.sql.SQLException {
+    	final TeiidDriver driver = new TeiidDriver();
+
+    	// check if this is embedded connection 
+    	if (getServerName() == null) {
+	        final Properties props = buildEmbeddedProperties(userName, password);	 
+	        String url = new JDBCURL(getDatabaseName(), null, props).getJDBCURL();
+	        return driver.connect(url, props);    		    		
+    	}
+    	
+    	// if not proceed with socket connection.
+        validateProperties(userName,password);
+        final Properties props = buildServerProperties(userName, password);	        
+        return driver.connect(buildURL(), props);
+    	
+    }
+    
+	private Properties buildEmbeddedProperties(final String userName, final String password) {
+		Properties props = buildProperties(userName, password);
+		return props;
+	}    
+	
+   /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return buildURL(); 
+    }
+
+    // --------------------------------------------------------------------------------------------
+    //                        P R O P E R T Y   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    /**
+     * Returns the port number.
+     * @return the port number
+     */
+    public int getPortNumber() {
+        return portNumber;
+    }
+
+    /**
+     * Returns the name of the server.
+     * @return the name of the server
+     */
+    public String getServerName() {
+        return serverName;
+    }
+    
+    /**
+     * Returns a flag indicating whether to create a secure connection or not. 
+     * @return True if using secure mms: protocol, false for normal mm: protocol.
+     * @since 5.0.2
+     */
+    public boolean isSecure() {
+        return this.secure;
+    }
+
+    /**
+     * Returns a string containing a comma delimited list of alternate 
+     * MetaMatrix Server(s).  
+     * 
+     * The list will be in the form of server2[:port2][,server3[:port3]].  If no 
+     * alternate servers have been defined <code>null</code> is returned. 
+     * @return A comma delimited list of server:port or <code>null</code> If 
+     * no alternate servers are defined.
+     * @since 5.5
+     */
+    public String getAlternateServers() {
+    	if ( this.alternateServers != null && this.alternateServers.length() < 1 )
+    		return null;
+        return this.alternateServers;
+    }
+
+    /**
+     * Sets the portNumber.
+     * @param portNumber The portNumber to set
+     */
+    public void setPortNumber(final int portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    /**
+     * Sets the serverName.
+     * @param serverName The serverName to set
+     */
+    public void setServerName(final String serverName) {
+        this.serverName = serverName;
+    }
+    
+    /**
+     * Sets the secure flag to use mms: protocol instead of the default mm: protocol. 
+     * @param secure True to use mms:
+     * @since 5.0.2
+     */
+    public void setSecure(final boolean secure) {
+        this.secure = secure;
+    }
+    
+    /**
+     * Sets a list of alternate server(s) that can be used for 
+     * connection fail-over.
+     * 
+     * The form of the list should be server2[:port2][,server3:[port3][,...]].  
+     * 
+     * If ":port" is omitted, the port defined by <code>portNumber</code> is used.
+     * 
+     * If <code>servers</code> is empty or <code>null</code>, the value of
+     * <code>alternateServers</code> is cleared.
+     * @param servers A comma delimited list of alternate 
+     * Server(s):Port(s) to use for connection fail-over. If blank or 
+     * <code>null</code>, the list is cleared.
+     * @since 5.5
+     */
+    public void setAlternateServers(final String servers) {
+    	this.alternateServers = servers;
+    	if ( this.alternateServers != null && this.alternateServers.length() < 1 )
+    		this.alternateServers = null;
+    }
+    
+    
+    // --------------------------------------------------------------------------------------------
+    //                  V A L I D A T I O N   M E T H O D S
+    // --------------------------------------------------------------------------------------------
+
+    /**
+     * Return the reason why the supplied port number may be invalid, or null
+     * if it is considered valid.
+     * @param portNumber a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setPortNumber(int)
+     */
+    public static String reasonWhyInvalidPortNumber( final int portNumber) {
+        if ( portNumber == 0 ) {
+            return null;        // default is always fine
+        }
+        if ( portNumber < 1 ) {
+            return JDBCPlugin.Util.getString("MMDataSource.Port_number_must_be_positive"); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Return the reason why the supplied server name may be invalid, or null
+     * if it is considered valid.
+     * @param serverName a possible value for the property
+     * @return the reason why the property is invalid, or null if it is considered valid
+     * @see #setServerName(String)
+     * */
+    public static String reasonWhyInvalidServerName( final String serverName ) {
+        if ( serverName == null || serverName.trim().length() == 0 ) {
+            return JDBCPlugin.Util.getString("MMDataSource.Server_name_required"); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * The reason why "socketsPerVM" is invalid.
+     * @param value of "socketsPerVM" property
+     * @return reason
+     */
+    public static String reasonWhyInvalidSocketsPerVM(final String socketsPerVM) {
+        if (socketsPerVM != null) {
+            int value = -1;
+            try {
+                value = Integer.parseInt(socketsPerVM);
+            } catch (Exception e) {                
+            }
+            
+            if (value <= 0) {
+                return JDBCPlugin.Util.getString("MMDataSource.Sockets_per_vm_invalid"); //$NON-NLS-1$
+            }
+        }
+        return null;
+    }
+    
+    
+    /**
+     * The reason why "stickyConnections" is invalid.
+     * @param value of "stickyConnections" property
+     * @return reason
+     */
+    public static String reasonWhyInvalidStickyConnections(final String stickyConnections) {
+        if (stickyConnections != null) {
+            if ((! stickyConnections.equalsIgnoreCase("true")) &&    //$NON-NLS-1$ 
+                (! stickyConnections.equalsIgnoreCase("false"))) {   //$NON-NLS-1$          
+                return JDBCPlugin.Util.getString("MMDataSource.Sticky_connections_invalid"); //$NON-NLS-1$
+            }
+        }
+        return null;
+    }
+ 
+    /**
+     * The reason why "alternateServers" is invalid.
+     * @param value of "alternateServers" property
+     * @return reason
+     */
+    public static String reasonWhyInvalidAlternateServers(final String alternateServers) {
+    	if ( alternateServers == null || alternateServers.trim().length() < 1 )
+    		return null;
+    	
+    	String[] as = alternateServers.split( TeiidURL.COMMA_DELIMITER);
+    	String sReason = null;
+    	String reason = ""; //$NON-NLS-1$
+    	int reasonCount = 0;
+    	final String newline = System.getProperty("line.separator"); //$NON-NLS-1$
+    	
+    	for ( int i = 0; i < as.length; i++ ) {
+    		String[] server = as[i].split( TeiidURL.COLON_DELIMITER );
+
+    		if ( server.length < 1 || server.length > 2 ) {
+    			// ie "server:31000:an invalid value"
+    			// ie "server,server:31000"
+				return JDBCPlugin.Util.getString("MMDataSource.Alternate_Servers_format"); //$NON-NLS-1$
+    		}
+
+    		// check the server name portion
+    		sReason = reasonWhyInvalidServerName(server[0] );
+    		if ( sReason != null ) {
+   				reason += (reason.length() > 0 ? newline : "" ) + sReason; //$NON-NLS-1$
+   				reasonCount++;
+   				sReason = null;
+    		}
+    		
+    		if ( server.length > 1 ) {
+				// check the port portion
+				int port = 0;
+				// parse the int from the string
+				try { port = Integer.parseInt(server[1]); }
+				catch ( NumberFormatException e ) { 
+	    			// ie "server:invalid_port"
+	   				reason += (reason.length() > 0 ? newline : "" )  //$NON-NLS-1$
+						+ JDBCPlugin.Util.getString("MMDataSource.serverPort_must_be_a_number"); //$NON-NLS-1$
+					reasonCount++;
+				}
+				sReason = reasonWhyInvalidPortNumber(port);
+				if ( sReason != null ) {
+	   				reason += (reason.length() > 0 ? newline : "" ) + sReason; //$NON-NLS-1$
+	   				reasonCount++;
+	   				sReason = null;
+				}
+    		}
+    	}
+    	if ( reasonCount < 1 ) return null;
+    	return JDBCPlugin.Util.getString("MMDataSource.alternateServer_is_invalid", String.valueOf(reasonCount), reason); //$NON-NLS-1$
+    }
+ 
+    /** 
+     * @return Returns the transparentFailover.
+     */
+    public String getAutoFailover() {
+        return this.autoFailover;
+    }
+
+    /** 
+     * @param transparentFailover The transparentFailover to set.
+     */
+    public void setAutoFailover(String autoFailover) {
+        this.autoFailover = autoFailover;
+    }
+
+	public String getDiscoveryStrategy() {
+		return discoveryStrategy;
+	}
+
+	public void setDiscoveryStrategy(String discoveryStrategy) {
+		this.discoveryStrategy = discoveryStrategy;
+	}
+}
+


Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidDriver.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.metamatrix.common.util.ApplicationInfo;
+import com.metamatrix.common.util.PropertiesUtils;
+
+/**
+ * JDBC Driver class for Teiid Embedded and Teiid Server. This class automatically registers with the 
+ * {@link DriverManager}
+ * 
+ *  The accepted URL format for the connection
+ *  <ul>
+ *  	<li> Server/socket connection:<b> jdbc:teiid:&lt;vdb-name&gt;@mm[s]://&lt;server-name&gt;:&lt;port&gt;;[user=&lt;user-name&gt;][password=&lt;user-password&gt;][other-properties]*</b>
+ *  	<li> Embedded  connection:<b> jdbc:teiid:&lt;vdb-name&gt;@&lt;file-path-to-deploy.properties&gt;;[user=&lt;user-name&gt;][password=&lt;user-password&gt;][other-properties]*</b>
+ *  </ul>
+ *  The user, password properties are needed if the user authentication is turned on. All the "other-properties" are simple name value pairs.
+ *  Look at {@link JDBCURL} KNOWN_PROPERTIES for list of known properties allowed.
+ */
+
+public class TeiidDriver implements Driver {
+	
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+	static final String DRIVER_NAME = "Teiid JDBC Driver"; //$NON-NLS-1$
+	
+    private static TeiidDriver INSTANCE = new TeiidDriver();
+        
+    static {
+        try {
+            DriverManager.registerDriver(INSTANCE);
+        } catch(SQLException e) {
+            // Logging
+            String logMsg = JDBCPlugin.Util.getString("MMDriver.Err_registering", e.getMessage()); //$NON-NLS-1$
+            logger.log(Level.SEVERE, logMsg);
+        }
+    }
+
+    public static TeiidDriver getInstance() {
+        return INSTANCE;
+    }
+    
+    /**
+     * Should be a singleton and only constructed in {@link #getInstance}.
+     */
+    public TeiidDriver() {
+        // this is not singleton, if you want singleton make this private.
+    }
+
+    public Connection connect(String url, Properties info) throws SQLException {
+
+    	if (EmbeddedProfile.acceptsURL(url)) {
+    		return EmbeddedProfile.connect(url, info);
+    	}
+    	else if (SocketProfile.acceptsURL(url)) {
+    		return SocketProfile.connect(url, info);
+    	}
+    	return null;
+    }
+    
+    /**
+     * Returns true if the driver thinks that it can open a connection to the given URL.
+     * Expected URL format for server mode is
+     * jdbc:teiid::VDB at mm://server:port;version=1;user=username;password=password
+     * 
+     * @param The URL used to establish a connection.
+     * @return A boolean value indicating whether the driver understands the subprotocol.
+     * @throws SQLException, should never occur
+     */
+    public boolean acceptsURL(String url) throws SQLException {
+    	return EmbeddedProfile.acceptsURL(url) || SocketProfile.acceptsURL(url);
+    }
+
+    /**
+     * Get's the driver's major version number. Initially this should be 1.
+     * @return major version number of the driver.
+     */
+    public int getMajorVersion() {
+        return ApplicationInfo.getInstance().getMajorReleaseVersion();
+    }
+
+    /**
+     * Get's the driver's minor version number. Initially this should be 0.
+     * @return major version number of the driver.
+     */
+    public int getMinorVersion() {
+        return ApplicationInfo.getInstance().getMinorReleaseVersion();
+    }
+
+    public String getDriverName() {
+        return DRIVER_NAME;
+    }
+    
+    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+        if(info == null) {
+            info = new Properties();
+        } else {
+        	info = PropertiesUtils.clone(info);
+        }
+
+        // construct list of driverPropertyInfo objects
+        List<DriverPropertyInfo> driverProps = new LinkedList<DriverPropertyInfo>();
+
+        if (EmbeddedProfile.acceptsURL(url)) {
+        	EmbeddedProfile.parseURL(url, info);
+        } else if (SocketProfile.acceptsURL(url)) {
+        	SocketProfile.parseURL(url, info);
+        }
+
+        for (String property: JDBCURL.KNOWN_PROPERTIES) {
+        	DriverPropertyInfo dpi = new DriverPropertyInfo(property, info.getProperty(property));
+        	if (property.equals(BaseDataSource.VDB_NAME)) {
+        		dpi.required = true;
+        	}
+        	driverProps.add(dpi);
+        }
+        
+        // create an array of DriverPropertyInfo objects
+        DriverPropertyInfo [] propInfo = new DriverPropertyInfo[driverProps.size()];
+
+        // copy the elements from the list to the array
+        return driverProps.toArray(propInfo);
+    }    
+    
+    /**
+     * This method returns true if the driver passes jdbc compliance tests.
+     * @return true if the driver is jdbc complaint, else false.
+     */
+    public boolean jdbcCompliant() {
+        return false;
+    }
+}
+
+


Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidSQLException.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,228 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.NoRouteToHostException;
+import java.net.UnknownHostException;
+import java.sql.SQLException;
+
+import org.teiid.client.security.InvalidSessionException;
+import org.teiid.client.security.LogonException;
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+
+
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.api.exception.query.ProcedureErrorInstructionException;
+import com.metamatrix.core.MetaMatrixCoreException;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+
+/**
+ * Teiid specific SQLException
+ */
+
+public class TeiidSQLException extends SQLException {
+
+	private static final long serialVersionUID = 3672305321346173922L;
+
+	/**
+     * No-arg constructor required by Externalizable semantics.
+     */
+    public TeiidSQLException() {
+        super();
+    }
+    
+    public TeiidSQLException(String reason) {
+        super(reason, SQLStates.DEFAULT);
+    }
+
+    public TeiidSQLException(String reason, String state) {
+        super(reason, state);
+    }    
+    
+    public static TeiidSQLException create(Throwable exception) {
+        if (exception instanceof TeiidSQLException) {
+            return (TeiidSQLException)exception;
+        }
+        return create(exception, exception.getMessage());
+    }
+        
+    public TeiidSQLException(Throwable ex, String reason, String sqlState) {
+        super(reason, sqlState); // passing the message to the super class constructor.
+        initCause(ex);
+    }
+    
+    private TeiidSQLException(SQLException ex, String message, boolean addChildren) {
+        super(message, ex.getSQLState() == null ? SQLStates.DEFAULT : ex.getSQLState(), ex.getErrorCode());
+        
+        if (addChildren) {
+        	SQLException childException = ex; // this a child to the SQLException constructed from reason
+
+            while (childException != null) {
+                if (childException instanceof TeiidSQLException) {
+                    super.setNextException(ex);
+                    break;
+                } 
+                super.setNextException(new TeiidSQLException(childException, getMessage(childException, null),false));
+                childException = childException.getNextException();
+            }
+        }
+    }    
+    public static TeiidSQLException create(Throwable exception, String message) {
+		message = getMessage(exception, message);
+		Throwable origException = exception;
+		if (exception instanceof TeiidSQLException) {
+			if (message.equals(exception.getMessage())) {
+				return (TeiidSQLException) exception;
+			}
+		}
+		if (exception instanceof SQLException) {
+			return new TeiidSQLException((SQLException) exception, message, true);
+		}
+		String sqlState = SQLStates.DEFAULT;
+
+		exception = findRootException(exception);
+
+		sqlState = determineSQLState(exception, sqlState);
+		return new TeiidSQLException(origException, message, sqlState);
+	}
+
+    /** 
+     * @param exception
+     * @param sqlState
+     * @return
+     */
+    private static String determineSQLState(Throwable exception,
+                                            String sqlState) {
+        if (exception instanceof InvalidSessionException) { 
+			sqlState = SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION;
+		} else if (exception instanceof LogonException) { 
+			sqlState = SQLStates.INVALID_AUTHORIZATION_SPECIFICATION_NO_SUBCLASS;
+		} else if (exception instanceof ProcedureErrorInstructionException) {
+			sqlState = SQLStates.VIRTUAL_PROCEDURE_ERROR;
+		} else if (exception instanceof MetaMatrixProcessingException) {
+			sqlState = SQLStates.USAGE_ERROR;
+		} else if (exception instanceof UnknownHostException
+				|| exception instanceof ConnectException
+				|| exception instanceof MalformedURLException
+				|| exception instanceof NoRouteToHostException
+				|| exception instanceof ConnectionException) {
+			sqlState = SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION;
+		} else if (exception instanceof IOException) {
+			sqlState = SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION;
+		} else if (exception instanceof MetaMatrixCoreException) {
+            if (exception instanceof CommunicationException) {
+                sqlState = SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION;
+            }
+            
+            Throwable originalException = exception;
+            exception = originalException.getCause();
+            exception = findRootException(exception);
+            
+            if (exception instanceof CommunicationException) {
+                sqlState = SQLStates.USAGE_ERROR;
+                exception = exception.getCause();
+            }
+            
+            if (exception != null && exception != originalException) {
+                sqlState = determineSQLState(exception, sqlState);
+            }
+		}
+        return sqlState;
+    }
+
+    /** 
+     * @param exception
+     * @return
+     */
+    private static Throwable findRootException(Throwable exception) {
+        if (exception instanceof MetaMatrixRuntimeException) {
+        	while (exception.getCause() != exception
+        			&& exception.getCause() != null) {
+        		exception = exception.getCause();
+        	}
+        	if (exception instanceof MetaMatrixRuntimeException) {
+        		MetaMatrixRuntimeException runtimeException = (MetaMatrixRuntimeException) exception;
+        		while (runtimeException.getChild() != exception
+        				&& runtimeException.getChild() != null) {
+        			if (runtimeException.getChild() instanceof MetaMatrixRuntimeException) {
+        				runtimeException = (MetaMatrixRuntimeException) runtimeException
+        						.getChild();
+        			} else {
+        				exception = runtimeException.getChild();
+        				break;
+        			}
+        		}
+        	}
+        }
+        return exception;
+    }
+    
+    /** 
+     * @param exception
+     * @param message
+     * @return
+     * @since 4.1
+     */
+    private static String getMessage(Throwable exception,
+                                     String message) {
+        if (message == null) {
+            message = exception.getMessage();
+            if (message == null) {
+                message = exception.getClass().getName();
+            }
+        }
+        return message;
+    }
+    
+    
+    /** 
+     * @see java.lang.Throwable#getCause()
+     * @since 4.3.2
+     */
+    public Throwable getCause() {
+        if (this.getNextException() != null) {
+        	return getNextException();
+        }
+        return super.getCause();
+    }
+
+    /** 
+     * @see org.teiid.jdbc.api.SQLException#isSystemErrorState()
+     * @since 4.3
+     */
+    public boolean isSystemErrorState() {
+        return SQLStates.isSystemErrorState(getSQLState());
+    }
+
+    /** 
+     * @see org.teiid.jdbc.api.SQLException#isUsageErrorState()
+     * @since 4.3
+     */
+    public boolean isUsageErrorState() {
+        return SQLStates.isUsageErrorState(getSQLState());
+    }
+}
\ No newline at end of file

Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidStatement.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+import java.util.Collection;
+
+import org.teiid.client.plan.Annotation;
+import org.teiid.client.plan.PlanNode;
+
+
+
+/**
+ * This interface provides methods in 
+ * addition to the standard JDBC methods. 
+ */
+public interface TeiidStatement extends java.sql.Statement {
+
+    /**
+     * Get the execution property value.
+     * @param name Execution property name
+     * @return Execution property value or null if not set
+     */
+    String getExecutionProperty(String name);
+
+    /**
+     * Set the execution property value.
+     * @param name Execution property name
+     * @param value Execution property value 
+     */
+    void setExecutionProperty(String name, String value);
+
+    /**
+     * Obtain the query plan object representation from the last 
+     * command executed on this Statement, if a query plan was 
+     * requested in the command.  If no plan was requested, this 
+     * method will return null.
+     * @return PlanNode representing the root of the query plan
+     */
+    PlanNode getPlanDescription();
+    
+    /**
+     * Obtain the query planner debug log from the last command 
+     * executed on this Statement, if it was requested with
+     * OPTION DEBUG.  If no debug output was requested, this 
+     * method will return null. 
+     * @return Debug log or null if no log exists
+     */
+    String getDebugLog();
+    
+    /**
+     * Get collection of annotations from the query planner from
+     * the last command executed on the Statement  
+     * @return Collection of {@link Annotation}s, may return null
+     */
+    Collection<Annotation> getAnnotations();
+     
+    /**
+     * Attach a stylesheet to be applied on the server for XML queries 
+     * executed with this Statement.
+     * @param reader Reader for reading a stylesheet in XML
+     * @throws IOException If an error occurs reading the stylesheet
+     * @deprecated
+     */
+    void attachStylesheet(Reader reader) throws IOException;    
+
+    /**
+     * Clear any previously attached stylesheet for this Statement object.
+     * @deprecated
+     */
+    void clearStylesheet();    
+
+    /**
+     * Get ID for last execution which can be used for matching up executions
+     * on the client side with executions in the server logs.
+     * @return String identifier for the last execution
+     */
+    String getRequestIdentifier();
+    
+    /**
+     * Set the per-statement security payload.  This optional payload will 
+     * accompany each request to the data source(s) so that the connector
+     * will have access to it.
+     * 
+     * <p>To remove an existing payload from a statement, call this method
+     * with a <code>null</code> argument.</p>
+     *   
+     * @param payload The payload that is to accompany requests executed
+     * from this statement.
+     * @since 4.2
+     */
+    void setPayload(Serializable payload);
+}


Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/WarningUtil.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLWarning;
+import java.util.List;
+
+import org.teiid.client.SourceWarning;
+
+
+
+/**
+ * Utilities for creating SQLWarnings.  
+ */
+class WarningUtil {
+
+    private WarningUtil() {
+    }
+    
+    /**
+     * Used to wrap warnings/exceptions into SQLWarning.
+     * The chain of warnings is translated into a chain of SQLWarnings.
+     * @param reason String object which is the description of the warning.
+     * @param ex Throwable object which needs to be wrapped.
+     */
+    static SQLWarning createWarning(Throwable ex) {
+        if(ex instanceof SourceWarning) {
+        	SourceWarning exception = (SourceWarning)ex;
+        	if (exception.isPartialResultsError()) {
+        		PartialResultsWarning warning = new PartialResultsWarning(JDBCPlugin.Util.getString("WarningUtil.Failures_occurred")); //$NON-NLS-1$
+        		warning.addConnectorFailure(exception.getConnectorBindingName(), TeiidSQLException.create(exception));
+        		return warning;
+        	}
+        }
+        //## JDBC4.0-begin ##
+        return new SQLWarning(ex);
+        //## JDBC4.0-end ##
+		/*## JDBC3.0-JDK1.5-begin ##
+		return new SQLWarning(ex.getMessage()); 
+	      ## JDBC3.0-JDK1.5-end ##*/
+        
+    }
+
+    /**
+     * Convert a List of warnings from the server into a single SQLWarning chain.
+     * @param exceptions List of exceptions from server
+     * @return Chain of SQLWarning corresponding to list of exceptions
+     */
+    static SQLWarning convertWarnings(List<Exception> exceptions) {
+        if(exceptions == null || exceptions.size() == 0) {
+            return null;    
+        }
+        SQLWarning warning = null;
+
+        for (Exception ex : exceptions) {
+            SQLWarning newWarning = createWarning(ex); 
+            if(warning == null) {
+                warning = newWarning;
+            } else {
+                warning.setNextWarning(newWarning);
+            }
+        }
+     
+        return warning;   
+    }
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/WrapperImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.Wrapper;
+//## JDBC4.0-end ##
+
+import com.metamatrix.core.util.ArgCheck;
+
+public class WrapperImpl 
+	//## JDBC4.0-begin ##
+	implements Wrapper 
+	//## JDBC4.0-end ##	
+	{
+	public boolean isWrapperFor(Class<?> iface) throws SQLException {
+		ArgCheck.isNotNull(iface);
+		
+		return iface.isInstance(this);
+	}
+
+	public <T> T unwrap(Class<T> iface) throws SQLException {
+		if (!isWrapperFor(iface)) {
+			throw new SQLException(JDBCPlugin.Util.getString("WrapperImpl.wrong_class", iface)); //$NON-NLS-1$
+		}
+		
+		return iface.cast(this);
+	}
+
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/XAConnectionImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import javax.sql.ConnectionEvent;
+import javax.sql.ConnectionEventListener;
+//## JDBC4.0-begin ##
+import javax.sql.StatementEventListener;
+//## JDBC4.0-end ##
+import javax.sql.XAConnection;
+import javax.transaction.xa.XAResource;
+
+/**
+ * Implementation of XAConnection.
+ */
+public class XAConnectionImpl implements XAConnection{
+	
+    interface ConnectionSource {
+
+        ConnectionImpl createConnection() throws SQLException;
+        
+    }
+    
+    private final class CloseInterceptor implements
+                                        InvocationHandler {
+        
+        private ConnectionImpl proxiedConnection;
+        
+        CloseInterceptor(ConnectionImpl connection) {
+            this.proxiedConnection = connection; 
+        }
+
+        public Object invoke(Object proxy,
+                             Method method,
+                             Object[] args) throws Throwable {
+            if ("close".equals(method.getName())) {  //$NON-NLS-1$
+                this.proxiedConnection.recycleConnection();
+                XAConnectionImpl.this.notifyListener(null);
+                return null;
+            }
+            
+            try {
+				return method.invoke(this.proxiedConnection, args);
+			} catch (InvocationTargetException e) {
+				//TODO: notify listeners about critical errors
+				throw e.getTargetException();
+			}
+        }
+    }
+
+    private HashSet listeners;
+	private XAResource resource;
+	private ConnectionImpl connection;
+	private ConnectionSource cs;
+		
+    private boolean isClosed;
+        
+    public static XAConnectionImpl newInstance (ConnectionSource cs){
+        return new XAConnectionImpl(cs);
+    }
+    
+	public XAConnectionImpl(ConnectionSource cs){
+	    this.cs = cs;
+	}
+		
+	public Connection getConnection() throws SQLException{
+        ConnectionImpl conn = getMMConnection();
+		
+		Connection result = (Connection)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {Connection.class}, new CloseInterceptor(conn));
+		
+		return result;
+	}
+	
+	ConnectionImpl getMMConnection() throws SQLException {
+	    if(isClosed){
+            throw new SQLException(JDBCPlugin.Util.getString("MMXAConnection.connection_is_closed")); //$NON-NLS-1$
+        }
+        
+        if(connection == null){
+            try{
+                connection = cs.createConnection();
+            }catch(SQLException e){                
+                notifyListener(e);
+                throw e;
+            }       
+        }
+        
+        return connection;
+	}
+	    
+	public synchronized void addConnectionEventListener(ConnectionEventListener listener){
+		if(listeners == null){
+			listeners = new HashSet();
+		}
+		this.listeners.add(listener);
+	}
+	
+	public synchronized void removeConnectionEventListener(ConnectionEventListener listener){
+		if(listeners == null){
+			return;
+		}
+		this.listeners.remove(listener);
+	}
+	
+	public XAResource getXAResource() throws SQLException{
+		if(resource == null){
+			resource = XAResourceImpl.newInstance(this);
+		}
+		return resource;
+	}
+	
+	public void close()throws SQLException{		
+		if(connection != null && !connection.isClosed()){
+			connection.close();			
+		}
+        isClosed = true;
+	}
+	
+	/**
+	 * Notify listeners, if there is any, about the connection status.
+	 * If e is null, the connection is properly closed.
+	 * @param e
+	 */
+	protected synchronized void notifyListener(SQLException e){
+		if(listeners != null && !listeners.isEmpty()){
+			Iterator iter = listeners.iterator();
+			while(iter.hasNext()){
+				ConnectionEventListener listener = (ConnectionEventListener)iter.next();
+				if(e == null){
+					//no exception
+					listener.connectionClosed(new ConnectionEvent(this));
+				}else{
+					//exception occurred
+					listener.connectionErrorOccurred(new ConnectionEvent(this, e));	
+				}
+			}
+		}	
+	}
+
+	//## JDBC4.0-begin ##
+	public void addStatementEventListener(StatementEventListener arg0) {
+	}
+
+	public void removeStatementEventListener(StatementEventListener arg0) {
+	}
+	//## JDBC4.0-end ##
+}

Copied: trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java (from rev 1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/XAResourceImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java	                        (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,209 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.net.CommunicationException;
+
+
+/**
+ * Implementation of XAResource.
+ */
+public class XAResourceImpl implements XAResource{
+	private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
+
+	private XAConnectionImpl mmConnection;
+	private int timeOut;
+    
+    public static XAResourceImpl newInstance (XAConnectionImpl mmConnection){
+        return new XAResourceImpl(mmConnection);
+    }
+    
+	public XAResourceImpl(XAConnectionImpl mmConnection){
+		this.mmConnection = mmConnection;
+	}	
+	    
+	/**
+     * @see javax.transaction.xa.XAResource#commit(javax.transaction.xa.Xid, boolean)
+     */
+    public void commit(Xid xid, boolean onePhase) throws XAException {
+    	XidImpl mmXid = getMMXid(xid);
+		try{
+			getMMConnection().commitTransaction(mmXid, onePhase); 	
+		}catch(SQLException e){
+			String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedCommitTXN", xid, onePhase ? "true":"false"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			throw handleError(e, logMsg);
+		}
+    }
+
+    private XAException handleError(Exception e,String logMsg) {
+        logger.log(Level.SEVERE, logMsg, e);
+
+        if(e instanceof TeiidSQLException){
+            Throwable ex = ((TeiidSQLException)e).getCause();
+            if(ex instanceof XAException){
+                return (XAException)ex;
+            }
+            if (ex instanceof XATransactionException) {
+                return ((XATransactionException)ex).getXAException();
+            }
+        }
+        return new XAException(XAException.XAER_RMERR);
+    }
+
+	/**
+     * @see javax.transaction.xa.XAResource#end(javax.transaction.xa.Xid, int)
+     */
+    public void end(Xid xid, int flag) throws XAException {
+    	XidImpl mmXid = getMMXid(xid);
+		try{
+            getMMConnection().endTransaction(mmXid, flag); 	
+		}catch(SQLException e){
+            String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedEndTXN", xid, new Integer(flag)); //$NON-NLS-1$
+            throw handleError(e, logMsg);
+		}
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#forget(javax.transaction.xa.Xid)
+     */
+    public void forget(Xid xid) throws XAException {
+    	XidImpl mmXid = getMMXid(xid);
+		try{
+            getMMConnection().forgetTransaction(mmXid); 	
+        }catch(SQLException e){
+            String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedForgetTXN", xid); //$NON-NLS-1$
+            throw handleError(e, logMsg);
+        }
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#getTransactionTimeout()
+     */
+    public int getTransactionTimeout() throws XAException {
+        return timeOut;
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#isSameRM(javax.transaction.xa.XAResource)
+     */
+    public boolean isSameRM(XAResource arg0) throws XAException {
+    	if (arg0 == this) {
+    		return true;
+    	}
+        if (!(arg0 instanceof XAResourceImpl)) {
+        	return false;
+        }
+        XAResourceImpl other = (XAResourceImpl)arg0;
+		try {
+			return this.getMMConnection().isSameProcess(other.getMMConnection());
+		} catch (CommunicationException e) {
+			throw handleError(e, JDBCPlugin.Util.getString("MMXAResource.FailedISSameRM")); //$NON-NLS-1$
+		}
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#prepare(javax.transaction.xa.Xid)
+     */
+    public int prepare(Xid xid) throws XAException {
+    	XidImpl mmXid = getMMXid(xid);
+		try{
+			return getMMConnection().prepareTransaction(mmXid); 	
+        }catch(SQLException e){
+            String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedPrepareTXN", xid); //$NON-NLS-1$
+            throw handleError(e, logMsg);
+        }
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#recover(int)
+     */
+    public Xid[] recover(int flag) throws XAException {
+        try{
+			return getMMConnection().recoverTransaction(flag); 	
+        }catch(SQLException e){
+            String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedRecoverTXN", flag); //$NON-NLS-1$
+            throw handleError(e, logMsg);
+        }
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#rollback(javax.transaction.xa.Xid)
+     */
+    public void rollback(Xid xid) throws XAException {
+    	XidImpl mmXid = getMMXid(xid);
+		try{
+            getMMConnection().rollbackTransaction(mmXid); 	
+        }catch(SQLException e){
+            String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedRollbackTXN", xid); //$NON-NLS-1$
+            throw handleError(e, logMsg);
+        }
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#setTransactionTimeout(int)
+     */
+    public boolean setTransactionTimeout(int seconds) throws XAException {
+        timeOut = seconds;
+        return true;
+    }
+
+    /**
+     * @see javax.transaction.xa.XAResource#start(javax.transaction.xa.Xid, int)
+     */
+    public void start(Xid xid, int flag) throws XAException {
+    	XidImpl mmXid = getMMXid(xid);
+		try{
+			getMMConnection().startTransaction(mmXid, flag, timeOut); 	
+        }catch(SQLException e){
+            String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedStartTXN", xid, new Integer(flag)); //$NON-NLS-1$
+            handleError(e, logMsg);
+        }
+    }
+        
+    private ConnectionImpl getMMConnection() throws XAException{
+    	try{
+    	    return this.mmConnection.getMMConnection();
+    	}catch(SQLException e){
+    		throw new XAException(XAException.XAER_RMFAIL);
+    	}
+    }
+    
+    /**
+	 * @param xid
+	 * @return
+     * @throws XAException
+	 */
+	private XidImpl getMMXid(Xid originalXid) {
+		return new XidImpl(originalXid);
+	}
+}

Copied: trunk/client/src/main/resources/META-INF (from rev 1983, trunk/client-jdbc/src/main/resources/META-INF)

Copied: trunk/client/src/main/resources/org/teiid/jdbc (from rev 1983, trunk/client-jdbc/src/main/resources/org/teiid/jdbc)

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,927 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.ResultSetImpl;
+import org.teiid.jdbc.StatementImpl;
+
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+import com.metamatrix.common.util.TimestampWithTimezone;
+import com.metamatrix.query.unittest.TimestampUtil;
+
+public class TestAllResultsImpl {
+
+	private static final long REQUEST_ID = 0;
+	private static final int TYPE_FORWARD_ONLY = ResultSet.TYPE_FORWARD_ONLY;
+	private static final int TYPE_SCROLL_SENSITIVE = ResultSet.TYPE_SCROLL_SENSITIVE;
+
+	private StatementImpl statement;
+
+	@Before public void setUp() throws Exception {
+		statement = TestMMResultSet.createMockStatement(TYPE_SCROLL_SENSITIVE);
+	}
+	
+	/** test hasNext(), actual result set should return FALSE. */
+	@Test public void testHasNext1() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+		while (rs.next()) {
+			// just walk through
+		}
+
+		boolean actual = rs.hasNext();
+		boolean expected = false;
+		assertEquals(expected, actual); 
+
+		rs.close();
+	}
+
+	/** test hasNext(), actual result set should return TRUE. */
+	@Test public void testHasNext2() throws Exception {
+		List[] results = exampleResults1(5);
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+
+		for (int i = 1; i < results.length; i++) {
+			rs.next();
+		}
+
+		boolean actual = rs.hasNext();
+		boolean expected = true;
+		assertEquals(expected, actual); 
+
+		rs.close();
+	}
+
+	/**
+	 * test next(), whether the result set's cursor is positioned on next row or
+	 * not
+	 */
+	@Test public void testNext1() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+
+		// point to first row
+		boolean actual = rs.next();
+		boolean expected = true;
+		assertEquals(" Actual doesn't match with expected. ", expected, actual); //$NON-NLS-1$
+
+		rs.close();
+	}
+
+	/** test next(), walk through all rows of a result set and compare each row. */
+	@Test public void testNext2() throws Exception {
+		List[] results = exampleResults1(5);
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+
+		int i = 0;
+		while (rs.next()) {
+			// walk through and compare
+			List actual = rs.getCurrentRecord();
+			List expected = results[i];
+			assertEquals(expected, actual); 
+			i++;
+		}
+
+		rs.close();
+	}
+
+	/** test next(), get result set and close without walking through */
+	@Test public void testNext3() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+		assertEquals(new Integer(0), new Integer(rs.getRow())); 
+
+		rs.close();
+	}
+
+	/** test next(), walk through partial rows of a result set */
+	@Test public void testNext4() throws Exception {
+		List[] results = exampleResults1(5);
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+
+		for (int i = 0; i < results.length - 1; i++) {
+			rs.next();
+			List actual = rs.getCurrentRecord();
+			List expected = results[i];
+			assertEquals(expected, actual); 
+		}
+
+		rs.close();
+	}
+
+	/** test next(), when hasNext() == false */
+	@Test public void testNext5() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+		while (rs.next()) {
+			// just walk through until hasNext() == false;
+		}
+
+		boolean actual = rs.hasNext();
+		boolean expected = false;
+		assertEquals(expected, actual); 
+
+		rs.close();
+	}
+
+	/** test getObject() at columnIndex = 2 of 5th row */
+	@Test public void testGetObject1() throws Exception {
+		List[] results = exampleResults2();
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+				statement);
+
+		String actual = null;
+		String expected = "a3"; //$NON-NLS-1$
+
+		// move cursor to the 4th row
+		for (int i = 0; i < results.length - 2; i++) {
+			rs.next();
+		}
+
+		// only compare the 4th row's 2nd column
+		if (rs.next()) {
+			actual = (String) rs.getObject(2);
+		}
+
+		assertEquals(expected, actual); 
+
+		rs.close();
+	}
+
+	/** Should fail, test getObject() at wrong columnIndex */
+	@Test public void testGetObject2() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+				statement);
+
+		if (rs.next()) {
+			// ERROR -- there are totally only 2 columns inside result set, 6 is
+			// an invalid one
+			try {
+				rs.getObject(6);
+			} catch (Exception e) {
+				if (e instanceof IllegalArgumentException) {
+					// OK
+				}
+			}
+		}
+
+		rs.close();
+	}
+
+	@Test public void testGetRow() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+				statement);
+
+		int expected = 0;
+		assertEquals(expected, rs.getRow()); 
+
+		if (rs.next()) {
+			expected = 1;
+			assertEquals(expected, rs.getRow()); 
+		}
+		rs.close();
+
+	}
+
+	@Test public void testPrevious() throws Exception {
+		List[] results = exampleResults1(5);
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+				statement);
+
+		while (rs.next()) {
+			// just walk to the end;
+		}
+
+		// walk reversely;
+		int i = results.length - 1;
+		while (rs.previous()) {
+			List expected = new ArrayList();
+			expected.add(new Integer(i + 1));
+			assertEquals(expected, rs.getCurrentRecord()); 
+			i--;
+		}
+
+		rs.close();
+	}
+
+	@Test public void testGetCurrentRecord() throws Exception {
+		List[] results = exampleResults2();
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+				statement);
+
+		rs.next();
+		List actual = rs.getCurrentRecord();
+		assertEquals(results[0], actual); 
+		rs.close();
+	}
+
+	@Test public void testGetMetaData() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+				statement);
+		ResultSetMetaData rmetadata = rs.getMetaData();
+		assertEquals(2, rmetadata.getColumnCount()); 
+
+		String[] columnNames = columnNames();
+		String[] dataTypes = dataTypes();
+		for (int i = 0; i < 2; i++) {
+			assertEquals(columnNames[i], rmetadata.getColumnName(i + 1)); 
+			assertEquals(dataTypes[i], rmetadata.getColumnTypeName(i + 1)); 
+		}
+		rs.close();
+	}
+
+	@Test public void testResultsWarnings() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+				statement);
+		rs.close();
+	}
+
+	@Test public void testClose() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+				statement);
+		rs.close();
+		verify(statement, times(0)).close();
+	}
+
+	@Test public void testGetFetchSize() throws Exception {
+		StatementImpl s = mock(StatementImpl.class);
+		stub(s.getFetchSize()).toReturn(500);
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(), s);
+		assertEquals(500, rs.getFetchSize()); 
+		rs.setFetchSize(100);
+		assertEquals(100, rs.getFetchSize());
+	}
+
+	// //////////////////////Functions refer to ResultSet's TYPE_FORWARD_ONLY///
+	// /////////////////
+	@Test(expected=SQLException.class) public void testIsAfterLast1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+		rs.last();
+	}
+
+	@Test(expected=SQLException.class) public void testAfterLast1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+		rs.afterLast();
+	}
+
+	@Test public void testIsBeforeFirst1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		// right before the first row
+		boolean actual = rs.isBeforeFirst();
+		assertEquals(true, actual); 
+		rs.close();
+	}
+
+	@Test public void testIsBeforeFirst2() throws Exception {
+		ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+		// right before the first row
+		boolean actual = rs.isBeforeFirst();
+		assertEquals(false, actual); 
+		rs.close();
+	}
+
+	@Test(expected=SQLException.class) public void testBeforeFirst1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		// move cursor to the first row
+		rs.next();
+
+		// move back to before first row
+		rs.beforeFirst();
+	}
+
+	@Test public void testIsFirst1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		// move cursor to the first row
+		rs.next();
+		boolean actual = rs.isFirst();
+		assertEquals(true, actual); 
+		rs.close();
+	}
+
+	@Test public void testIsFirst2() throws Exception {
+		ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+		// move cursor to the first row
+		rs.next();
+		boolean actual = rs.isFirst();
+		assertEquals(false, actual); 
+		rs.close();
+	}
+
+	@Test(expected=SQLException.class) public void testFirst1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		// move cursor to the first row
+		rs.next();
+		rs.first();
+	}
+
+	@Test(expected=SQLException.class) public void testFirst2() throws Exception {
+		ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+		// move cursor to the first row
+		rs.next();
+		rs.first();
+	}
+
+	@Test public void testFindColumn() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+				statement);
+
+		assertEquals(1, rs.findColumn("IntNum")); //$NON-NLS-1$ 
+		rs.close();
+	}
+
+	@Test public void testIsLast1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		// move cursor to the last row
+		boolean actual = rs.isLast();
+		assertEquals(false, actual); 
+	}
+
+	@Test public void testIsLast2() throws Exception {
+		ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+		// move cursor to the last row
+		boolean actual = rs.isLast();
+		assertEquals(false, actual); 
+	}
+
+	@Test(expected=SQLException.class) public void testLast1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		rs.last();
+	}
+
+	@Test public void testRelative1() throws Exception {
+		ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+				statement);
+
+		// move to 1st row
+		rs.next();
+		// move to 2nd row
+		boolean actual = rs.relative(1);
+		assertEquals(true, actual); 
+		assertEquals(2, rs.getRow()); 
+
+		actual = rs.relative(-1);
+		assertEquals(true, actual); 
+		assertEquals(1, rs.getRow()); 
+		rs.close();
+	}
+
+	@Test(expected=SQLException.class) public void testAbsolute1() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+		rs.absolute(1);
+	}
+
+	// //////////Functions refer to other types other than ResultSet's
+	// TYPE_FORWARD_ONLY//////
+
+	@Test public void testAfterLast1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// move cursor right past the last row
+		rs.afterLast();
+
+		// the expected row == 0 because it pasts the last row
+		assertEquals(0, rs.getRow()); 
+		rs.close();
+	}
+
+	@Test public void testIsAfterLast1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// the last row
+		rs.last();
+		boolean actual = rs.isAfterLast();
+		assertEquals(false, actual); 
+
+		// move after the last row
+		rs.next();
+		actual = rs.isAfterLast();
+		assertEquals(true, actual); 
+		rs.close();
+	}
+
+	@Test public void testIsBeforeFirst1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// right before the first row
+		boolean actual = rs.isBeforeFirst();
+		assertEquals(true, actual); 
+		rs.close();
+	}
+
+	@Test public void testBeforeFirst1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// move cursor to the first row
+		rs.next();
+		rs.next();
+
+		// move back to before first row
+		rs.beforeFirst();
+
+		assertEquals(0, rs.getRow()); 
+		rs.close();
+	}
+
+	@Test public void testIsFirst1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// move cursor to the first row
+		rs.next();
+		boolean actual = rs.isFirst();
+		assertEquals(true, actual); 
+
+		// check row number
+		assertEquals(1, rs.getRow()); 
+		rs.close();
+	}
+
+	@Test public void testFirst1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// move cursor to the first row
+		boolean actual = rs.first();
+		assertEquals(true, actual); 
+		assertEquals(1, rs.getRow()); 
+
+		// move cursor to the first row starting from the last row
+		rs.afterLast();
+		actual = rs.first();
+		assertEquals(true, actual); 
+		assertEquals(1, rs.getRow()); 
+
+		// move cursor to the first row from random number;
+		rs.absolute(3);
+		actual = rs.first();
+		assertEquals(true, actual); 
+		assertEquals(1, rs.getRow()); 
+		rs.close();
+	}
+
+	@Test public void testIsLast1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// check whether the movement of cursor is successful
+		rs.last();
+		boolean actual = rs.isLast();
+		assertEquals(true, actual); 
+
+		// check row number
+		assertEquals(5, rs.getRow()); 
+		rs.close();
+	}
+
+	@Test public void testLast1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// check whether the movement of cursor is successful
+		boolean actual = rs.last();
+		assertEquals(true, actual); 
+
+		// check weather the current row is the last row
+		assertEquals(5, rs.getRow()); 
+		rs.close();
+	}
+
+	/** normal relative move, only including moving from valid row to valid one */
+	@Test public void testRelative1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// move to 1st row
+		rs.next();
+		// move to 2nd row
+		boolean actual = rs.relative(1);
+
+		assertEquals(true, actual); 
+		assertEquals(2, rs.getRow()); 
+
+		actual = rs.relative(-1);
+		assertEquals(true, actual); 
+		assertEquals(1, rs.getRow()); 
+		rs.close();
+	}
+
+	/** normal relative move, including moving from valid row to invalid one */
+	@Test public void testRelative1b() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// move to 1st row
+		rs.next();
+		// move to 2nd row
+		boolean actual = rs.relative(1);
+		actual = rs.relative(-1);
+
+		// test if move before first
+		actual = rs.relative(-3);
+		// relative should return false when not on a row
+		assertEquals(false, actual); 
+		assertEquals(0, rs.getRow()); 
+
+		// test if move after last
+		// this line is very important because it positions the cursor in a
+		// valid row!!!
+		rs.beforeFirst();
+		rs.next();
+		actual = rs.relative(7);
+		// should return false because it's not on a valid row
+		assertEquals(false, actual); 
+		assertEquals(0, rs.getRow()); 
+		rs.close();
+	}
+
+	/** check only moving from an invalid row */
+	@Test public void testRelative1c() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// test if move before first will work or not
+		// default to before first
+		try {
+			rs.relative(-2);
+			fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+		} catch (SQLException e) {
+
+		}
+		assertEquals(
+				" Should still be before the first row ", true, rs.isBeforeFirst()); //$NON-NLS-1$
+		assertEquals(0, rs.getRow()); 
+
+		try {
+			rs.relative(2);
+			fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+		} catch (SQLException e) {
+
+		}
+		assertEquals(
+				" Should still be before the first row ", true, rs.isBeforeFirst()); //$NON-NLS-1$
+		assertEquals(0, rs.getRow()); 
+		// test if move after last will work or not
+
+		rs.afterLast();
+
+		try {
+			rs.relative(2);
+			fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+		} catch (SQLException e) {
+
+		}
+		assertEquals(
+				" Should still be after the last row. ", true, rs.isAfterLast()); //$NON-NLS-1$
+		assertEquals(0, rs.getRow()); 
+		try {
+			rs.relative(-2);
+			fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+		} catch (SQLException e) {
+
+		}
+		assertEquals(
+				" Should still be after the last row. ", true, rs.isAfterLast()); //$NON-NLS-1$
+		assertEquals(0, rs.getRow()); 
+		rs.close();
+	}
+
+	/** test only valid row in result set */
+	@Test public void testAbsolute1a() throws Exception {
+		ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+		// start from beginning
+		boolean actual = rs.absolute(1);
+		assertEquals(true, actual); 
+		assertEquals(1, rs.getRow()); 
+
+		actual = rs.absolute(12);
+		assertEquals(false, actual); 
+		assertEquals(0, rs.getRow()); 
+
+		// start from right after last
+		rs.afterLast();
+		actual = rs.absolute(-1);
+		assertEquals(true, actual); 
+		assertEquals(5, rs.getRow()); 
+
+		actual = rs.absolute(-2);
+		assertEquals(true, actual); 
+		assertEquals(4, rs.getRow()); 
+		rs.close();
+	}
+
+	/** test only valid row in result set */
+	@Test public void testAbsolute2a() throws Exception {
+		ResultSetImpl rs = helpGetNoResults(TYPE_SCROLL_SENSITIVE);
+
+		// start from beginning
+		assertEquals(false, rs.absolute(1)); 
+		assertEquals(0, rs.getRow()); 
+
+		// start from right after last
+		rs.afterLast();
+		assertEquals(false, rs.absolute(-1)); 
+		assertEquals(0, rs.getRow()); 
+
+		rs.close();
+	}
+	
+	/**
+	 * 3 batches
+	 */
+	@Test public void testMoreResults() throws Exception {
+		int fetchSize = 5;
+		int batchLength = 4;
+		int totalLength = 10;
+		
+		ResultSetImpl rs = helpTestBatching(statement, fetchSize, batchLength,
+				totalLength);
+		
+		assertTrue(rs.absolute(6));
+		assertTrue(rs.absolute(-1));
+		assertFalse(rs.next());
+		
+		for (int i = 0; i < totalLength; i++) {
+			assertTrue(rs.previous());
+		}
+	}
+	
+	static ResultSetImpl helpTestBatching(StatementImpl statement, int fetchSize, int batchLength,
+			int totalLength) throws InterruptedException, ExecutionException,
+			MetaMatrixProcessingException, SQLException, TimeoutException {
+		DQP dqp = mock(DQP.class);
+		stub(statement.getDQP()).toReturn(dqp);
+		stub(statement.getFetchSize()).toReturn(fetchSize);
+		for (int i = batchLength; i < totalLength; i += batchLength) {
+			//forward requests
+			ResultsFuture<ResultsMessage> nextBatch = mock(ResultsFuture.class);
+			stub(nextBatch.get(Matchers.anyLong(), (TimeUnit)Matchers.anyObject())).toReturn(exampleResultsMsg4(i + 1, Math.min(batchLength, totalLength - i), fetchSize, i + batchLength >= totalLength));
+			stub(dqp.processCursorRequest(REQUEST_ID, i + 1, fetchSize)).toReturn(nextBatch);
+			
+			if (i + batchLength < totalLength) {
+				//backward requests
+				ResultsFuture<ResultsMessage> previousBatch = mock(ResultsFuture.class);
+				stub(previousBatch.get(Matchers.anyLong(), (TimeUnit)Matchers.anyObject())).toReturn(exampleResultsMsg4(i - batchLength + 1, i, fetchSize, false));
+				stub(dqp.processCursorRequest(REQUEST_ID, i, fetchSize)).toReturn(previousBatch);
+			}
+		}
+		
+		ResultsMessage msg = exampleResultsMsg4(1, batchLength, fetchSize, batchLength == totalLength);
+		return new ResultSetImpl(msg, statement);
+	}
+
+	// /////////////////////Helper Method///////////////////
+	static List<Object>[] exampleResults1(int length) {
+		return exampleResults1(length, 1);
+	}
+	
+	static List<Object>[] exampleResults1(int length, int begin) {
+		List<Object>[] results = new List[length];
+
+		for (int i = 0; i < results.length; i++) {
+			results[i] = new ArrayList<Object>();
+			results[i].add(new Integer(begin + i));
+		}
+
+		return results;
+	}
+
+	private List[] exampleResults2() {
+		List[] results = new List[5];
+
+		for (int i = 0; i < results.length; i++) {
+			results[i] = new ArrayList();
+			results[i].add(new Integer(i));
+			results[i].add(new String("a" + i)); //$NON-NLS-1$
+		}
+
+		return results;
+	}
+
+	private String[] columnNames() {
+		String[] names = new String[2];
+		names[0] = new String("IntNum"); //$NON-NLS-1$
+		names[1] = new String("StringNum"); //$NON-NLS-1$
+		return names;
+	}
+
+	private String[] dataTypes() {
+		String[] types = new String[2];
+		types[0] = MMJDBCSQLTypeInfo.INTEGER;
+		types[1] = MMJDBCSQLTypeInfo.STRING;
+		return types;
+	}
+
+	private ResultSetImpl helpGetResultSetImpl(int type)
+			throws SQLException {
+		ResultsMessage rsMsg = exampleResultsMsg2();
+		statement = TestMMResultSet.createMockStatement(type);
+		ResultSetImpl rs = new ResultSetImpl(rsMsg, statement);
+		return rs;
+	}
+
+	private ResultSetImpl helpGetNoResults(int type) throws SQLException {
+		ResultsMessage rsMsg = exampleResultsMsg3();
+		statement = TestMMResultSet.createMockStatement(type);
+		ResultSetImpl rs = new ResultSetImpl(rsMsg, statement);
+		return rs;
+	}
+
+	/** without metadata info. */
+	private ResultsMessage exampleResultsMsg1() {
+		return exampleMessage(exampleResults1(5), new String[] { "IntNum" }, new String[] { MMJDBCSQLTypeInfo.INTEGER }); //$NON-NLS-1$
+	}
+	
+	private ResultsMessage exampleMessage(List<Object>[] results, String[] columnNames, String[] datatypes) {
+		RequestMessage request = new RequestMessage();
+		request.setExecutionId(REQUEST_ID);
+		ResultsMessage resultsMsg = new ResultsMessage(request);
+		resultsMsg.setResults(results);
+		resultsMsg.setColumnNames(columnNames);
+		resultsMsg.setDataTypes(datatypes); 
+		resultsMsg.setFinalRow(results.length);
+		resultsMsg.setLastRow(results.length);
+		resultsMsg.setFirstRow(1);
+		return resultsMsg;
+	}
+
+	/** without metadata info. */
+	private ResultsMessage exampleResultsMsg2() {
+		return exampleMessage(exampleResults2(), new String[] { "IntNum", "StringNum" }, new String[] { MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.STRING }); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/** with limited metadata info. */
+	private ResultsMessage exampleResultsMsg2a() {
+		ResultsMessage resultsMsg = exampleResultsMsg2();
+		List[] results = exampleResults2();
+		resultsMsg.setDataTypes(dataTypes());
+		resultsMsg.setColumnNames(columnNames());
+
+		resultsMsg.setResults(results);
+		resultsMsg.setFinalRow(results.length);
+		resultsMsg.setLastRow(results.length);
+		resultsMsg.setFirstRow(1);
+		return resultsMsg;
+	}
+
+	/** no rows. */
+	private ResultsMessage exampleResultsMsg3() {
+		return exampleMessage(new List[0], new String[] { "IntNum", "StringNum" }, new String[] { MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.STRING }); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	
+	private static ResultsMessage exampleResultsMsg4(int begin, int length, int fetchSize, boolean lastBatch) {
+		RequestMessage request = new RequestMessage();
+		request.setExecutionId(REQUEST_ID);
+		ResultsMessage resultsMsg = new ResultsMessage(request);
+		List[] results = exampleResults1(length, begin);
+		resultsMsg.setResults(results);
+		resultsMsg.setColumnNames(new String[] { "IntKey" }); //$NON-NLS-1$
+		resultsMsg.setDataTypes(new String[] { MMJDBCSQLTypeInfo.INTEGER }); 
+		resultsMsg.setFirstRow(begin);
+		if (lastBatch) {
+			resultsMsg.setFinalRow(begin + results.length - 1);
+		}
+		resultsMsg.setLastRow(begin + results.length - 1);
+		return resultsMsg;
+	}
+
+	@Test public void testNotCallingNext() throws SQLException {
+		ResultSetImpl cs = new ResultSetImpl(exampleResultsMsg2a(),
+				statement);
+
+		try {
+			cs.getObject(1);
+			fail("Exception expected"); //$NON-NLS-1$
+		} catch (SQLException e) {
+			assertEquals("The cursor is not on a valid row.", e.getMessage()); //$NON-NLS-1$
+		}
+	}
+	
+	@Test public void testDateType() throws SQLException {
+		RequestMessage request = new RequestMessage();
+		request.setExecutionId(REQUEST_ID);
+		ResultsMessage resultsMsg = new ResultsMessage(request);
+		resultsMsg.setResults(new List[] {Arrays.asList(new Timestamp(0))});
+		resultsMsg.setColumnNames(new String[] { "TS" }); //$NON-NLS-1$
+		resultsMsg.setDataTypes(new String[] { MMJDBCSQLTypeInfo.TIMESTAMP }); 
+		resultsMsg.setFirstRow(1);
+		resultsMsg.setFinalRow(1);
+		resultsMsg.setLastRow(1);
+		ResultSetImpl rs = new ResultSetImpl(resultsMsg, statement);
+		assertTrue(rs.next());
+		//assumes the mock statement is setup with GMT-5 server and GMT-6 client
+		
+		//will adjust ahead one hour
+		assertEquals(new Timestamp(3600000), rs.getObject(1));
+		
+		//will be the same as the original
+		assertEquals(new Timestamp(0), rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("GMT-05:00")))); //$NON-NLS-1$
+	}
+	
+	@Test public void testWasNull() throws SQLException{
+		ResultsMessage message = exampleMessage(new List[] { Arrays.asList((String)null), Arrays.asList("1") }, new String[] { "string" }, //$NON-NLS-1$
+				new String[] { MMJDBCSQLTypeInfo.STRING });
+		ResultSetImpl rs = new ResultSetImpl(message, statement);
+		assertTrue(rs.next());
+		assertEquals(Boolean.FALSE.booleanValue(), rs.getBoolean(1));
+		assertTrue(rs.wasNull());
+		assertEquals(0, rs.getShort(1));
+		assertTrue(rs.wasNull());
+		assertEquals(0, rs.getInt(1));
+		assertTrue(rs.wasNull());
+		assertEquals(0l, rs.getLong(1));
+		assertTrue(rs.wasNull());
+		assertEquals(0f, rs.getFloat(1), 0);
+		assertTrue(rs.wasNull());		
+		assertEquals(0d, rs.getDouble(1), 0);
+		assertTrue(rs.wasNull());
+		assertNull(rs.getString(1));
+		assertTrue(rs.wasNull());
+		assertTrue(rs.next());
+		assertEquals(1, rs.getShort(1));
+		assertFalse(rs.wasNull());
+		assertFalse(rs.next());
+	}
+	
+	@Test public void testGetters() throws SQLException{
+		TimeZone.setDefault(TimeZone.getTimeZone("GMT-05:00")); //$NON-NLS-1$
+		ResultsMessage message = exampleMessage(new List[] { Arrays.asList(1, TimestampUtil.createTime(0, 0, 0), TimestampUtil.createDate(1, 1, 1), TimestampUtil.createTimestamp(1, 1, 1, 1, 1, 1, 1), "<root/>") }, //$NON-NLS-1$ 
+				new String[] { "int", "time", "date", "timestamp", "sqlxml" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 
+				new String[] { MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.TIME, MMJDBCSQLTypeInfo.DATE, MMJDBCSQLTypeInfo.TIMESTAMP, MMJDBCSQLTypeInfo.STRING });
+		TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$
+		ResultSetImpl rs = new ResultSetImpl(message, statement);
+		assertTrue(rs.next());
+		assertEquals(Boolean.TRUE.booleanValue(), rs.getBoolean(1));
+		assertEquals(1, rs.getShort(1));
+		assertEquals(1, rs.getInt(1));
+		assertEquals(1l, rs.getLong(1));
+		assertEquals(1f, rs.getFloat(1), 0);
+		assertEquals(1d, rs.getDouble(1), 0);
+		assertEquals("1", rs.getString(1)); //$NON-NLS-1$
+		assertEquals(Integer.valueOf(1), rs.getObject(1)); 
+		//the mock statement is in GMT-6 the server results are from GMT-5, so we expect them to display the same
+		assertEquals(TimestampUtil.createTime(0, 0, 0), rs.getTime(2)); 
+		assertEquals(TimestampUtil.createDate(1, 1, 1), rs.getDate(3));
+		assertEquals(TimestampUtil.createTimestamp(1, 1, 1, 1, 1, 1, 1), rs.getTimestamp(4));
+		assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root/>", rs.getSQLXML(5).getString()); //$NON-NLS-1$
+		try {
+			rs.getSQLXML(1);
+		} catch (SQLException e) {
+			assertEquals("Unable to transform the column value 1 to a SQLXML.", e.getMessage()); //$NON-NLS-1$
+		}
+		assertFalse(rs.next());
+		TimestampWithTimezone.resetCalendar(null);
+	}
+
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestBatchResults.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,375 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.teiid.jdbc.BatchResults.Batch;
+import org.teiid.jdbc.BatchResults.BatchFetcher;
+
+
+/** 
+ * @since 4.3
+ */
+public class TestBatchResults {
+	
+	static class MockBatchFetcher implements BatchFetcher {
+
+		private int totalRows = 50;
+		private boolean throwException;
+		List<Integer> batchCalls = new ArrayList<Integer>();
+		
+		public MockBatchFetcher() {
+			
+		}
+		
+		public MockBatchFetcher(int totalRows) {
+			this.totalRows = totalRows;
+		}
+
+		public Batch requestBatch(int beginRow) throws SQLException {
+			batchCalls.add(beginRow);
+			if (throwException) {
+				throw new SQLException();
+			}
+	        boolean isLast = false;
+	        int endRow = beginRow + 9;
+	        if (beginRow%10==0) {
+	        	endRow = beginRow - 9;
+	        }
+	        if(beginRow > endRow) {
+	            if(endRow < 1) {
+	                endRow = 1;
+	            }
+	            int i = beginRow;
+	            beginRow = endRow;
+	            endRow = i;
+	        } else if(endRow > totalRows) {
+	            endRow = totalRows;
+	            isLast = true;
+	        }
+			return new Batch(createBatch(beginRow, endRow), beginRow, endRow, isLast);
+		}
+
+		public void throwException() {
+			this.throwException = true;
+		}
+		
+	}
+    
+    private static List[] createBatch(int begin, int end) {
+        List[] results = new List[end - begin + 1];
+        for(int i=0; i<(end - begin + 1); i++) {
+            results[i] = new ArrayList();
+            results[i].add(new Integer(i+begin));
+        }
+        return results;
+    }
+    
+    private List[] createEmptyBatch() {
+        List[] results = new List[0];
+        return results;
+    }
+    
+    @Test public void testGetCurrentRow1() throws Exception{
+        //empty batch
+        BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+        assertNull(batchResults.getCurrentRow());
+        batchResults.next();
+        assertNull(batchResults.getCurrentRow());
+    }
+    
+    @Test public void testGetCurrentRow2() throws Exception{
+    	BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, true);
+        assertNull(batchResults.getCurrentRow());
+        batchResults.next();
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(1));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+    
+    @Test public void testHasNext1() throws Exception{
+        //empty batch
+    	BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+        assertFalse(batchResults.hasNext());
+    }
+    
+    @Test public void testHasNext2() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+        assertTrue(batchResults.hasNext());
+    }
+    
+    @Test public void testHasNext3() throws Exception{
+    	BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, true);
+        assertTrue(batchResults.hasNext());
+    }
+    
+    @Test public void testNext1() throws Exception{
+        //empty batch
+    	BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+        assertFalse(batchResults.next());
+    }
+    
+    @Test public void testNext2() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+        assertTrue(batchResults.next());
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(1));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+        assertFalse(batchResults.next());
+    }
+    
+    @Test public void testNext3() throws Exception{
+        //one row batch, multiple batches
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+        batchResults.setBatchFetcher(new MockBatchFetcher());
+        assertTrue(batchResults.next());
+        assertTrue(batchResults.next());
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(2));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+    
+    @Test public void testNext4() throws Exception{
+    	BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+        batchResults.setBatchFetcher(new MockBatchFetcher());
+        int i;
+        for(i=0; i<10; i++) {
+            assertTrue(batchResults.next());
+            List expectedResult = new ArrayList();
+            expectedResult.add(new Integer(i+1));
+            assertEquals(batchResults.getCurrentRow(), expectedResult);
+        }
+        while(batchResults.next()) {
+            List expectedResult = new ArrayList();
+            expectedResult.add(new Integer((i++)+1));
+            assertEquals(batchResults.getCurrentRow(), expectedResult);
+        }
+        assertFalse(batchResults.next());
+    }
+    
+    @Test public void testHasPrevious1() throws Exception{
+        //empty batch
+    	BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+        assertFalse(batchResults.hasPrevious());
+    }
+    
+    @Test public void testHasPrevious2() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+        assertFalse(batchResults.hasPrevious());
+        batchResults.next();
+        assertFalse(batchResults.hasPrevious());
+        batchResults.next();
+        assertTrue(batchResults.hasPrevious());
+    }
+    
+    @Test public void testPrevious1() throws Exception{
+        //empty batch
+    	BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+        assertFalse(batchResults.previous());
+    }
+    
+    @Test public void testPrevious2() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+        assertTrue(batchResults.next());
+        assertFalse(batchResults.previous());
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(1));
+        while(batchResults.next()) {
+        }
+        assertTrue(batchResults.previous());
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+    
+    @Test public void testPrevious3() throws Exception{
+        //one row batch, multiple batches
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+        batchResults.setBatchFetcher(new MockBatchFetcher());
+        assertFalse(batchResults.previous());
+        assertTrue(batchResults.next());
+        assertFalse(batchResults.previous());
+        while(batchResults.next()) {         
+        }
+        assertTrue(batchResults.previous());
+        while(batchResults.previous()) {         
+        }
+        batchResults.next();
+        batchResults.next();
+        batchResults.next();
+        batchResults.previous();
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(2));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+    
+    @Test public void testPrevious4() throws Exception{
+    	BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+        batchResults.setBatchFetcher(new MockBatchFetcher());
+        int i;
+        for(i=0; i<=10; i++) {
+            assertTrue(batchResults.next());
+        }
+        for(i=10; i>0; i--) {
+            batchResults.previous();
+            List expectedResult = new ArrayList();
+            expectedResult.add(new Integer(i));
+            assertEquals(batchResults.getCurrentRow(), expectedResult);
+        }
+    }
+    
+    @Test public void testAbsolute1() throws Exception{
+        //empty batch
+    	BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+        assertFalse(batchResults.absolute(0));
+        assertFalse(batchResults.absolute(1));
+    }
+    
+    @Test public void testAbsolute2() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+    	batchResults.setBatchFetcher(new MockBatchFetcher());
+        assertFalse(batchResults.absolute(0));
+        assertTrue(batchResults.absolute(1));
+        assertTrue(batchResults.absolute(1));
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(1));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+    
+    @Test public void testAbsolute3() throws Exception{
+        BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+        batchResults.setBatchFetcher(new MockBatchFetcher(200));
+        assertFalse(batchResults.absolute(0));
+        assertTrue(batchResults.absolute(11));
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(11));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+        assertTrue(batchResults.absolute(1));
+        expectedResult = new ArrayList();
+        expectedResult.add(new Integer(1));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+        assertTrue(batchResults.absolute(100));
+        expectedResult = new ArrayList();
+        expectedResult.add(new Integer(100));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+
+    //move backwards with absolute
+    @Test public void testAbsolute4() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+    	batchResults.setBatchFetcher(new MockBatchFetcher());
+        assertTrue(batchResults.absolute(10));
+        assertTrue(batchResults.absolute(2));
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(2));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+    }
+    
+    @Test public void testAbsolute5() throws Exception{
+        //one row batch
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+    	batchResults.setBatchFetcher(new MockBatchFetcher());
+        assertTrue(batchResults.absolute(-1));
+        List expectedResult = new ArrayList();
+        expectedResult.add(new Integer(50));
+        assertEquals(batchResults.getCurrentRow(), expectedResult);
+        
+        assertFalse(batchResults.absolute(-100));
+    }
+        
+    @Test public void testCurrentRowNumber() throws Exception {
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+        assertEquals(0, batchResults.getCurrentRowNumber());
+        batchResults.next();
+        assertEquals(1, batchResults.getCurrentRowNumber());
+        batchResults.next();
+        assertEquals(2, batchResults.getCurrentRowNumber());
+        assertFalse(batchResults.next());
+        assertEquals(2, batchResults.getCurrentRowNumber());
+    }
+    
+    @Test public void testSetException() throws Exception {
+    	BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+    	MockBatchFetcher batchFetcher = new MockBatchFetcher();
+    	batchResults.setBatchFetcher(batchFetcher);
+    	batchFetcher.throwException();
+    	batchResults.next();
+        try {
+            batchResults.hasNext();
+            fail("Expected exception, but did not get.");
+        }catch(SQLException e) {           
+        }
+    }
+    
+    @Test public void testBatching() throws Exception {               
+        BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+        MockBatchFetcher batchFetcher = new MockBatchFetcher(60);
+        batchResults.setBatchFetcher(batchFetcher);
+        
+        for(int i=0; i<45; i++) {    
+            assertTrue(batchResults.next());
+        }
+        
+        for(int i=0; i<44; i++) {
+            assertTrue(batchResults.previous());
+            assertEquals(new Integer(44 - i), batchResults.getCurrentRow().get(0));
+        }
+        
+        // verify batch calls
+        checkResults(new int[] { 
+            // going forwards - end > begin
+            11,
+            21,
+            31,
+            41,
+            // going backwards - begin > end
+            // last 3 batches were saved, only need the first 2 again
+            20,
+            10,
+        }, batchFetcher.batchCalls);        
+        
+        assertTrue(batchResults.absolute(50));
+        assertEquals(new Integer(50), batchResults.getCurrentRow().get(0));
+    }
+    
+    private void checkResults(int[] expectedCalls, List<Integer> batchCalls) {
+        assertEquals(expectedCalls.length, batchCalls.size());
+        
+        for(int i=0; i<batchCalls.size(); i++) {
+            int range = batchCalls.get(i);
+            int expected = expectedCalls[i];
+            assertEquals("On call " + i + " expected different begin", expected, range);
+        }
+    }
+        
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialClob;
+
+import org.teiid.jdbc.DataTypeTransformer;
+
+import junit.framework.TestCase;
+
+public class TestDataTypeTransformer extends TestCase {
+	
+	public void testClobToStringConversion() throws Exception {
+		Clob clob = new SerialClob("foo".toCharArray()); //$NON-NLS-1$
+		String value = DataTypeTransformer.getString(clob);
+		assertEquals("foo", value); //$NON-NLS-1$
+	}
+	
+	public void testInvalidTransformation() throws Exception {
+		try {
+			DataTypeTransformer.getDate(Integer.valueOf(1)); 
+			fail("exception expected"); //$NON-NLS-1$
+		} catch (SQLException e) {
+			assertEquals("Unable to transform the column value 1 to a Date.", e.getMessage()); //$NON-NLS-1$
+		}
+	}
+	
+	public void testGetByte() throws Exception {
+		assertEquals(0, DataTypeTransformer.getShort(null));
+	}
+
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.junit.Test;
+
+
+
+public class TestEmbeddedProfile {
+    EmbeddedProfile EmbeddedProfile = new EmbeddedProfile();
+    
+    /*
+     * Test method for 'com.metamatrix.jdbc.EmbeddedEmbeddedProfile.acceptsURL(String)'
+     * // (\\w:[\\\\,\\/]|file:\\/\\/|\\/|\\\\|(\\.){1,2}){1}
+     */
+    @Test public void testAcceptsURL() {    
+        
+        // ClassPath based URL
+        assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT at classpath:/dqp.properties;partialResultsMode=true")); //$NON-NLS-1$
+        
+        // These are specific to the MMorg.teiid.jdbc.EmbeddedProfile and should not be suported
+        assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT at mm://host:7001;version=1")); //$NON-NLS-1$
+        assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT at mms://host:7001;version=1")); //$NON-NLS-1$
+        
+        assertTrue(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT")); //$NON-NLS-1$
+        assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT!/path/foo.properties")); //$NON-NLS-1$
+        assertTrue(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT;")); //$NON-NLS-1$
+        assertTrue(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT;version=1;logFile=foo.txt")); //$NON-NLS-1$
+    }
+
+    @Test public void testParseURL() throws SQLException{
+        Properties p = new Properties();
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertEquals(2, p.size());        
+    }
+
+    @Test public void testParseURL2() throws SQLException {
+        Properties p = new Properties();       
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;version=3", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("3")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VERSION).equals("3")); //$NON-NLS-1$
+        assertEquals(4, p.size());
+    }
+    
+    @Test public void testParseURL3() throws SQLException{
+        Properties p = new Properties();
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT@/metamatrix/dqp/dqp.properties;version=4;autoCommitTxn=ON;partialResultsMode=YES;", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("4")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VERSION).equals("4")); //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP).equals("ON")); //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("YES")); //$NON-NLS-1$
+        assertEquals(6, p.size());        
+    }
+    
+    @Test public void testParseURL4() throws SQLException{
+        Properties p = new Properties();
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;partialResultsMode=true", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("true")); //$NON-NLS-1$
+        assertEquals(3, p.size());                
+    }
+    
+    @Test public void testParseURL5() throws SQLException{
+        Properties p = new Properties();
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+    }
+    
+    @Test public void testParseURL55() throws SQLException{
+        Properties p = new Properties();
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+    }    
+       
+    @Test public void testParseURL6() throws SQLException{
+        Properties p = new Properties();
+        org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;partialResultsMode=true;version=1", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("true")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("1")); //$NON-NLS-1$
+        assertEquals(5, p.size());                
+        
+    }
+    
+    @Test public void test() throws Exception {
+        try {
+            Class.forName("org.teiid.jdbc.TeiidDriver"); //$NON-NLS-1$
+            DriverManager.getConnection("jdbc:teiid:Parts at invalidConfig.properties;version=1"); //$NON-NLS-1$
+            fail();
+        } catch (SQLException e) {
+        }
+    }
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Licensed to Red Hat, Inc. under one or more contributor 
+ * license agreements.  See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mockito;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.metadata.ParameterInfo;
+import org.teiid.client.security.LogonResult;
+import org.teiid.jdbc.CallableStatementImpl;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.ResultSetImpl;
+import org.teiid.net.ServerConnection;
+
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+
+public class TestMMCallableStatement extends TestCase {
+	
+	public void testWasNull() throws Exception {
+		CallableStatementImpl mmcs = getCallableStatement();
+		
+		Map<Integer, Integer> params = new HashMap<Integer, Integer>();
+		mmcs.outParamIndexMap = params;
+		params.put(Integer.valueOf(1), Integer.valueOf(1));
+		params.put(Integer.valueOf(2), Integer.valueOf(2));
+		ResultSetImpl rs = Mockito.mock(ResultSetImpl.class);
+		mmcs.resultSet = rs;
+		Mockito.stub(rs.getOutputParamValue(1)).toReturn(null);
+		Mockito.stub(rs.getOutputParamValue(2)).toReturn(Boolean.TRUE);
+		mmcs.getBoolean(1);
+		assertTrue(mmcs.wasNull());
+		assertTrue(mmcs.getBoolean(2));
+		assertFalse(mmcs.wasNull());
+	}
+	
+	public void testGetOutputParameter() throws Exception {
+		CallableStatementImpl mmcs = getCallableStatement();
+		
+		RequestMessage request = new RequestMessage();
+		request.setExecutionId(1);
+		ResultsMessage resultsMsg = new ResultsMessage(request);
+		List[] results = new List[] {Arrays.asList(null, null, null), Arrays.asList(null, 1, 2)};
+		resultsMsg.setResults(results);
+		resultsMsg.setColumnNames(new String[] { "IntNum", "Out1", "Out2" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		resultsMsg.setDataTypes(new String[] { MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.INTEGER }); 
+		resultsMsg.setFinalRow(results.length);
+		resultsMsg.setLastRow(results.length);
+		resultsMsg.setFirstRow(1);
+		resultsMsg.setParameters(Arrays.asList(new ParameterInfo(ParameterInfo.RESULT_SET, 1), new ParameterInfo(ParameterInfo.OUT, 1), new ParameterInfo(ParameterInfo.OUT, 1)));
+		mmcs.createResultSet(resultsMsg);
+		assertEquals(1, mmcs.getInt(1));
+		assertEquals(2, mmcs.getInt(2));
+	}
+	
+	public void testUnknownIndex() throws Exception {
+		CallableStatementImpl mmcs = getCallableStatement();
+		
+		mmcs.outParamIndexMap = new HashMap<Integer, Integer>();
+		
+		try {
+			mmcs.getBoolean(0);
+			fail("expected exception"); //$NON-NLS-1$
+		} catch (IllegalArgumentException e) {
+			assertEquals("Parameter is not found at index 0.", e.getMessage());
+		}
+	}
+
+	private CallableStatementImpl getCallableStatement() throws SQLException {
+		ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+		ServerConnection sc = Mockito.mock(ServerConnection.class);
+		
+		Mockito.stub(sc.getLogonResult()).toReturn(new LogonResult());
+		Mockito.stub(conn.getServerConnection()).toReturn(sc);
+		
+		CallableStatementImpl mmcs = new CallableStatementImpl(conn, "{?=call x(?)}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+		return mmcs;
+	}
+
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMConnection.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.mockito.Mockito.*;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.teiid.client.DQP;
+import org.teiid.client.security.LogonResult;
+import org.teiid.client.security.SessionToken;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.jdbc.BaseDataSource;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.net.ServerConnection;
+
+
+public class TestMMConnection extends TestCase {
+
+	protected static final String STD_DATABASE_NAME         = "QT_Ora9DS"; //$NON-NLS-1$
+    protected static final int STD_DATABASE_VERSION      = 1; 
+    
+    static String serverUrl = "jdbc:metamatrix:QT_Ora9DS at mm://localhost:7001;version=1;user=metamatrixadmin;password=mm"; //$NON-NLS-1$
+
+    public TestMMConnection(String name) {
+        super(name);
+    }
+    
+    public static ConnectionImpl getMMConnection() {
+    	ServerConnection mock = mock(ServerConnection.class);
+    	DQP dqp = mock(DQP.class);
+    	try {
+			stub(dqp.start((XidImpl)Mockito.anyObject(), Mockito.anyInt(), Mockito.anyInt())).toAnswer(new Answer() {
+				@Override
+				public Object answer(InvocationOnMock invocation) throws Throwable {
+					return ResultsFuture.NULL_FUTURE;
+				}
+			});
+			stub(dqp.rollback((XidImpl)Mockito.anyObject())).toAnswer(new Answer() {
+				@Override
+				public Object answer(InvocationOnMock invocation) throws Throwable {
+					return ResultsFuture.NULL_FUTURE;
+				}
+			});
+			stub(dqp.rollback()).toAnswer(new Answer() {
+				@Override
+				public Object answer(InvocationOnMock invocation) throws Throwable {
+					return ResultsFuture.NULL_FUTURE;
+				}
+			});
+		} catch (XATransactionException e) {
+			throw new RuntimeException(e);
+		}
+    	stub(mock.getService(DQP.class)).toReturn(dqp);
+    	Properties props = new Properties();
+    	props.setProperty(BaseDataSource.VDB_NAME, STD_DATABASE_NAME);
+    	props.setProperty(BaseDataSource.VDB_VERSION, String.valueOf(STD_DATABASE_VERSION));
+    	props.setProperty(BaseDataSource.USER_NAME, "metamatrixadmin"); //$NON-NLS-1$
+    	stub(mock.getLogonResult()).toReturn(new LogonResult(new SessionToken(1, "metamatrixadmin"), STD_DATABASE_NAME,STD_DATABASE_VERSION , "fake")); //$NON-NLS-1$
+    	return new ConnectionImpl(mock, props, serverUrl);
+    }
+
+    public void testGetMetaData() throws Exception {
+        assertNotNull(getMMConnection().getMetaData());
+    }
+
+    public void testGetSchema() throws Exception {
+        assertEquals("Actual schema is not equql to the expected one. ", STD_DATABASE_NAME, getMMConnection().getVDBName()); //$NON-NLS-1$
+    }
+
+    public void testNativeSql() throws Exception {
+        String sql = "SELECT * FROM BQT1.SmallA"; //$NON-NLS-1$
+        assertEquals("Actual schema is not equql to the expected one. ", sql, getMMConnection().nativeSQL(sql)); //$NON-NLS-1$
+    }
+
+    /** test getUserName() through DriverManager */
+    public void testGetUserName2() throws Exception {        
+        assertEquals("Actual userName is not equal to the expected one. ", "metamatrixadmin", getMMConnection().getUserName()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+      
+    /** test isReadOnly default value on Connection */
+    public void testIsReadOnly() throws Exception {
+        assertEquals(false, getMMConnection().isReadOnly());
+    }
+
+    /** test setReadOnly on Connection */
+    public void testSetReadOnly1() throws Exception {
+    	ConnectionImpl conn = getMMConnection();
+        conn.setReadOnly(true);
+        assertEquals(true, conn.isReadOnly());
+    }
+
+    /** test setReadOnly on Connection during a transaction */
+    public void testSetReadOnly2() throws Exception {
+    	ConnectionImpl conn = getMMConnection();
+        conn.setAutoCommit(false);
+        try {
+            conn.setReadOnly(true);
+            fail("Error Expected"); //$NON-NLS-1$
+        } catch (SQLException e) {
+            // error expected
+        }
+    }
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMDriver.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,134 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.DriverPropertyInfo;
+import java.util.Properties;
+
+import org.teiid.net.TeiidURL;
+
+
+
+import junit.framework.TestCase;
+
+
+public class TestMMDriver extends TestCase {
+    TeiidDriver drv = new TeiidDriver();
+    public String localhost = "localhost"; //$NON-NLS-1$
+    
+    public TestMMDriver(String name)    {
+        super(name);
+    }
+    
+    /** Valid format of urls*/
+    public void testAcceptsURL1()  throws Exception   {
+        assertNotNull(drv);
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:jvdb at mm://localhost:1234")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234;version=x")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234,localhost2:12342,localhost3:12343")); //$NON-NLS-1$       
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mms://localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:jvdb at mms://localhost:1234")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234;version=x")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://localhost:1234,localhost2:12342,localhost3:12343")); //$NON-NLS-1$       
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mms://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mms://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://127.0.0.1:1234;logLevel=2")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mms://127.0.0.1:1234")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://127.0.0.1:1234,localhost.mydomain.com:63636;logLevel=2")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://my-host.mydomain.com:53535,127.0.0.1:1234")); //$NON-NLS-1$
+        assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb at mm://123.123.123.123:53535,127.0.0.1:1234")); //$NON-NLS-1$
+
+        //DQP type
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb at c:/dqp.properties;version=1")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb@/foo/dqp.properties;version=1")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb at ../foo/dqp.properties;version=1")); //$NON-NLS-1$
+        
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb at mm://localhost:port")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:vdb at localhost:port;version=x")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234,localhost2:12342,localhost3:12343")); //$NON-NLS-1$       
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;stickyConnections=false;socketsPerVM=4")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc:metamatrix:vdb at mm://my_host.mydomain.com:53535,127.0.0.1:1234")); //$NON-NLS-1$        
+    }
+
+    /** Invalid format of urls*/
+    public void testAcceptsURL2() throws Exception    {
+        assertNotNull(drv);
+        assertTrue(!drv.acceptsURL("jdbc:matamatrix:test")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("metamatrix:test")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc&matamatrix:test")); //$NON-NLS-1$
+        assertTrue(!drv.acceptsURL("jdbc;metamatrix:test")); //$NON-NLS-1$
+    }   
+
+    public void testParseURL() throws Exception{
+        Properties p = new Properties();
+        SocketProfile.parseURL("jdbc:metamatrix:BQT at mm://slwxp157:1234", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234")); //$NON-NLS-1$
+        assertEquals(3, p.size());        
+    }
+
+    public void testParseURL2() throws Exception {
+        Properties p = new Properties();       
+        SocketProfile.parseURL("jdbc:metamatrix:BQT at mms://slwxp157:1234;version=3", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("3")); //$NON-NLS-1$
+        assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mms://slwxp157:1234")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VERSION).equals("3")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals(BaseDataSource.DEFAULT_APP_NAME));
+        assertEquals(5, p.size());
+    }
+    
+    public void testParseURL3() throws Exception{
+        Properties p = new Properties();
+        SocketProfile.parseURL("jdbc:metamatrix:BQT at mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302;version=4;autoCommitTxn=ON;partialResultsMode=YES;ApplicationName=Client", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("4"));         //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP).equals("ON")); //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("YES")); //$NON-NLS-1$
+        assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VERSION).equals("4")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals("Client")); //$NON-NLS-1$
+        assertEquals(7, p.size());        
+    }    
+    
+    public void testGetPropertyInfo1() throws Exception {        
+        DriverPropertyInfo info[] = drv.getPropertyInfo("jdbc:metamatrix:vdb at mm://localhost:12345;applicationName=x", null); //$NON-NLS-1$
+
+        assertEquals(17, info.length);
+        assertEquals(false, info[0].required);
+        assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
+        assertEquals("x", info[0].value); //$NON-NLS-1$
+    }
+    
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,342 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.net.URLEncoder;
+import java.util.Properties;
+
+import org.teiid.jdbc.BaseDataSource;
+import org.teiid.jdbc.ExecutionProperties;
+import org.teiid.jdbc.JDBCURL;
+import org.teiid.net.TeiidURL;
+
+import junit.framework.TestCase;
+
+
+
+/** 
+ * @since 4.3
+ */
+public class TestMMJDBCURL extends TestCase {
+
+    // Need to allow embedded spaces and ='s within optional properties
+    public final void testCredentials() throws Exception {
+        String credentials = URLEncoder.encode("defaultToLogon,(system=BQT1 SQL Server 2000 Simple Cap,user=xyz,password=xyz)", "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+        JDBCURL url = new JDBCURL("jdbc:metamatrix:QT_sqls2kds at mm://slwxp136:43100;credentials="+credentials); //$NON-NLS-1$
+        Properties p = url.getProperties();
+        assertEquals("defaultToLogon,(system=BQT1 SQL Server 2000 Simple Cap,user=xyz,password=xyz)", p.getProperty("credentials"));  //$NON-NLS-1$//$NON-NLS-2$        
+    }
+       
+    public void testJDBCURLWithProperties() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1;configFile=testdata/bqt/dqp_stmt_e2e.xmi;disableLocalTxn=true;autoFailover=false"; //$NON-NLS-1$
+        
+        Properties expectedProperties = new Properties();
+        expectedProperties.setProperty("version", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("password", "***"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("logLevel", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("configFile", "testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS, "true"); //$NON-NLS-1$
+        expectedProperties.setProperty(TeiidURL.CONNECTION.AUTO_FAILOVER, "false"); //$NON-NLS-1$
+        JDBCURL url = new JDBCURL(URL); 
+        assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+        assertEquals("mm://localhost:12345", url.getConnectionURL()); //$NON-NLS-1$
+        assertEquals(expectedProperties, url.getProperties());
+    }
+    
+    public void testJDBCURLWithoutProperties() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345"; //$NON-NLS-1$
+        
+        JDBCURL url = new JDBCURL(URL); 
+        assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+        assertEquals("mm://localhost:12345", url.getConnectionURL()); //$NON-NLS-1$
+        assertEquals(new Properties(), url.getProperties());
+    }
+    
+    public void testCaseConversion() {
+        // Different case ------------------------------------HERE -v  ----------------and HERE  -v
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;VERSION=1;user=xyz;password=***;configFile=testdata/bqt/dqp_stmt_e2e.xmi"; //$NON-NLS-1$
+        
+        Properties expectedProperties = new Properties();
+        expectedProperties.setProperty("version", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("password", "***"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("configFile", "testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+        JDBCURL url = new JDBCURL(URL); 
+        assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+        assertEquals("mm://localhost:12345", url.getConnectionURL()); //$NON-NLS-1$
+        assertEquals(expectedProperties, url.getProperties());
+    }
+    
+    public void testWithExtraSemicolons() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1;;;configFile=testdata/bqt/dqp_stmt_e2e.xmi;;"; //$NON-NLS-1$
+        
+        Properties expectedProperties = new Properties();
+        expectedProperties.setProperty("version", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("password", "***"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("logLevel", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("configFile", "testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+        JDBCURL url = new JDBCURL(URL); 
+        assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+        assertEquals("mm://localhost:12345", url.getConnectionURL()); //$NON-NLS-1$
+        assertEquals(expectedProperties, url.getProperties());
+    }
+    
+    public void testWithWhitespace() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345; version =1;user= xyz ;password=***; logLevel = 1 ; configFile=testdata/bqt/dqp_stmt_e2e.xmi ;"; //$NON-NLS-1$
+        
+        Properties expectedProperties = new Properties();
+        expectedProperties.setProperty("version", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("password", "***"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("logLevel", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("configFile", "testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+        JDBCURL url = new JDBCURL(URL); 
+        assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+        assertEquals("mm://localhost:12345", url.getConnectionURL()); //$NON-NLS-1$
+        assertEquals(expectedProperties, url.getProperties());
+    }
+    
+    public void testNoPropertyValue() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;password=***;logLevel=;configFile="; //$NON-NLS-1$
+        
+        Properties expectedProperties = new Properties();
+        expectedProperties.setProperty("version", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("password", "***"); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("logLevel", ""); //$NON-NLS-1$ //$NON-NLS-2$
+        expectedProperties.setProperty("configFile", ""); //$NON-NLS-1$ //$NON-NLS-2$
+        JDBCURL url = new JDBCURL(URL); 
+        assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+        assertEquals("mm://localhost:12345", url.getConnectionURL()); //$NON-NLS-1$
+        assertEquals(expectedProperties, url.getProperties());
+    }
+    
+    public void testInvalidProtocol() {
+        String URL = "jdbc:monkeymatrix:bqt at mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+    
+    public void testNoVDBName() {
+        String URL = "jdbc:metamatrix:@mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }        
+    }
+    
+    public void testNoAtSignInURL() {
+        String URL = "jdbc:metamatrix:bqt!mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            // No @ sign is llowed as part of embedded driver now, 
+            // but this form of URL rejected in the acceptURL
+            //fail("Illegal argument should have failed.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+    
+    public void testMoreThanOneAtSign() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xy@;password=***;logLevel=1"; //$NON-NLS-1$
+        try {
+            // this allowed as customer properties can have @ in their properties
+            new JDBCURL(URL);            
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+    
+    public void testNoEqualsInProperty() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;password***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+    
+    public void testMoreThanOneEqualsInProperty() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;password==***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;password=***=;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;=password=***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+    
+    public void testNoKeyInProperty() {
+        String URL = "jdbc:metamatrix:bqt at mm://localhost:12345;version=1;user=xyz;=***;logLevel=1"; //$NON-NLS-1$
+        try {
+            new JDBCURL(URL);
+            fail("Illegal argument should have failed."); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+    
+    public void testConstructor() {
+        JDBCURL url = new JDBCURL("myVDB", "mm://myhost:12345",null); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("jdbc:teiid:myVDB at mm://myhost:12345", url.getJDBCURL()); //$NON-NLS-1$
+        
+        Properties props = new Properties();
+        props.setProperty(BaseDataSource.USER_NAME, "myuser"); //$NON-NLS-1$
+        props.setProperty(BaseDataSource.PASSWORD, "mypassword"); //$NON-NLS-1$
+        props.put("ClieNTtOKeN", new Integer(1)); //$NON-NLS-1$
+        url = new JDBCURL("myVDB", "mm://myhost:12345", props); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("jdbc:teiid:myVDB at mm://myhost:12345;user=myuser;password=mypassword", url.getJDBCURL()); //$NON-NLS-1$
+    }
+    
+    public void testConstructor_Exception() {
+        try {
+            new JDBCURL(null, "myhost", null); //$NON-NLS-1$
+            fail("Should have failed."); //$NON-NLS-1$
+        } catch (Exception e) {
+            
+        }
+        try {
+            new JDBCURL("  ", "myhost", null); //$NON-NLS-1$ //$NON-NLS-2$
+            fail("Should have failed."); //$NON-NLS-1$
+        } catch (Exception e) {
+            
+        }
+
+        try {
+        	// in embedded situation there is no connection url
+            new JDBCURL("myVDB", "  ", null); //$NON-NLS-1$ //$NON-NLS-2$
+        } catch (Exception e) {
+            
+        }
+    }
+    
+    public void testNormalize() {
+        Properties props = new Properties();
+        props.setProperty("UsEr", "myuser"); //$NON-NLS-1$ //$NON-NLS-2$
+        props.setProperty("pAssWOrD", "mypassword"); //$NON-NLS-1$ //$NON-NLS-2$
+        props.put("ClieNTtOKeN", new Integer(1)); //$NON-NLS-1$
+        JDBCURL.normalizeProperties(props);
+        assertEquals("myuser", props.getProperty(BaseDataSource.USER_NAME)); //$NON-NLS-1$
+        assertEquals("mypassword", props.getProperty(BaseDataSource.PASSWORD)); //$NON-NLS-1$
+    }
+    
+    public final void testEncodedPropertyProperties() throws Exception {
+        String password = "=@#^&*()+!%$^%@#_-)_~{}||\\`':;,./<>?password has = & %"; //$NON-NLS-1$
+        Properties props = new Properties();
+        props.setProperty("UsEr", "foo"); //$NON-NLS-1$ //$NON-NLS-2$
+        props.setProperty("PASswoRd", password); //$NON-NLS-1$
+        JDBCURL.normalizeProperties(props);
+        
+        assertEquals(password, props.getProperty("password"));  //$NON-NLS-1$
+        assertEquals("foo", props.getProperty("user"));  //$NON-NLS-1$//$NON-NLS-2$
+    }    
+   
+    public final void testEncodedPropertyInURL() throws Exception {
+        String password = "=@#^&*()+!%$^%@#_-)_~{}||\\`':;,./<>?password has = & %"; //$NON-NLS-1$
+        String encPassword = URLEncoder.encode(password, "UTF-8"); //$NON-NLS-1$
+        JDBCURL url = new JDBCURL("jdbc:metamatrix:QT_sqls2kds at mm://slwxp136:43100;PASswoRd="+encPassword); //$NON-NLS-1$
+        Properties p = url.getProperties();
+        assertEquals(password, p.getProperty("password"));  //$NON-NLS-1$
+    }   
+    
+    
+    public void testGetServerURL_NoProperties() {        
+        String result = new JDBCURL("jdbc:metamatrix:designtimecatalog at mm://slwxp172:44401;user=ddifranco;password=mm").getConnectionURL(); //$NON-NLS-1$
+        assertEquals("mm://slwxp172:44401", result);         //$NON-NLS-1$
+    }
+
+    public void testGetServerURL_Properties() {        
+        String result = new JDBCURL("jdbc:metamatrix:designtimecatalog at mm://slwxp172:44401;user=ddifranco;password=mm").getConnectionURL(); //$NON-NLS-1$
+        assertEquals("mm://slwxp172:44401", result);         //$NON-NLS-1$
+    }
+    
+    /**
+     * Test getServerURL with a valid URL and password that contains at least 
+     * one ASCII character in the range of 32 to 126 excluding the ; and = sign.
+     *
+     * @since 5.0.2
+     */
+    public void testGetServerURL_PasswordProperties() throws Exception {        
+        String result = null;
+        String srcURL = "jdbc:metamatrix:designtimecatalog at mm://slwxp172:44401;user=ddifranco;password="; //$NON-NLS-1$
+        String password = null;
+        String tgtURL = "mm://slwxp172:44401"; //$NON-NLS-1$
+        
+
+        for ( char ch = 32; ch <= 126; ch++ ) {
+            //exclude URL reserved characters
+        	if ( ch != ';' && ch != '=' && ch != '%') {
+        		password = ch+"mm"; //$NON-NLS-1$
+        		result = new JDBCURL(srcURL+URLEncoder.encode(password, "UTF-8")).getConnectionURL(); //$NON-NLS-1$ 
+        		assertEquals("Failed to obtain correct ServerURL when using password "+password,tgtURL, result);         //$NON-NLS-1$
+        	}
+        }
+        	
+    }
+    
+    public void testGetServerURL_2Servers() {       
+        String result = new JDBCURL("jdbc:metamatrix:designtimecatalog at mm://slwxp172:44401,slabc123:12345;user=ddifranco;password=mm").getConnectionURL(); //$NON-NLS-1$
+        assertEquals("mm://slwxp172:44401,slabc123:12345", result);         //$NON-NLS-1$
+    }
+
+    public void testBuildEmbeedURL() {
+    	JDBCURL url = new JDBCURL("vdb", "/home/foo/deploy.properties", new Properties()); //$NON-NLS-1$ //$NON-NLS-2$
+    	assertEquals("jdbc:teiid:vdb@/home/foo/deploy.properties", url.getJDBCURL()); //$NON-NLS-1$
+    	
+    	Properties p = new Properties();
+    	p.setProperty("user", "test"); //$NON-NLS-1$ //$NON-NLS-2$
+    	p.setProperty("password", "pass"); //$NON-NLS-1$ //$NON-NLS-2$
+    	p.setProperty("autoFailover", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+    	p.setProperty("any", "thing"); //$NON-NLS-1$ //$NON-NLS-2$
+    	
+    	url = new JDBCURL("vdb", "/home/foo/deploy.properties", p); //$NON-NLS-1$ //$NON-NLS-2$
+    	assertTrue(url.getJDBCURL().startsWith("jdbc:teiid:vdb@/home/foo/deploy.properties;user=test;")); //$NON-NLS-1$
+    	assertTrue(url.getJDBCURL().indexOf("any=thing")!=-1); //$NON-NLS-1$
+    	assertTrue(url.getJDBCURL().indexOf("password=pass")!=-1); //$NON-NLS-1$
+    	assertTrue(url.getJDBCURL().indexOf("autoFailover=true")!=-1); //$NON-NLS-1$
+    	
+    }
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,343 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.security.LogonResult;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.PreparedStatementImpl;
+import org.teiid.jdbc.TeiidSQLException;
+import org.teiid.net.ServerConnection;
+
+
+/**
+ * Test case to validate general operations on an <code>MMPreparedStatement
+ * </code> 
+ */
+public class TestMMPreparedStatement {
+
+	/**
+	 * Test that <code>MMPreparedStatement</code>'s <code>execute()</code> method
+	 * will throw a <code>MMSQLException</code> if a connection does not exist.
+	 * 
+	 * @throws Exception
+	 */
+	@Test(expected=TeiidSQLException.class) public void testUpdateException() throws Exception {
+		PreparedStatementImpl statement = getMMPreparedStatement("delete from table"); //$NON-NLS-1$
+		statement.execute();
+	}
+	
+	/**
+	 * Verify that the <code>executeBatch()</code> method of <code>
+	 * MMPreparedStatement</code> is resulting in the correct command, 
+	 * parameter values for each command of the batch, and the request type 
+	 * are being set in the request message that would normally be sent to the 
+	 * server.
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testBatchedUpdateExecution() throws Exception {
+		// Build up a fake connection instance for use with the prepared statement
+		ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+		DQP dqp = Mockito.mock(DQP.class);
+		ServerConnection serverConn = Mockito.mock(ServerConnection.class);
+		LogonResult logonResult = Mockito.mock(LogonResult.class);
+		
+		// stub methods
+		Mockito.stub(conn.getServerConnection()).toReturn(serverConn);
+		Mockito.stub(serverConn.getLogonResult()).toReturn(logonResult);
+		Mockito.stub(logonResult.getTimeZone()).toReturn(TimeZone.getDefault());
+
+		// a dummy result message that is specific to this test case
+		ResultsFuture<ResultsMessage> results = new ResultsFuture<ResultsMessage>(); 
+		Mockito.stub(dqp.executeRequest(Matchers.anyLong(), (RequestMessage)Matchers.anyObject())).toReturn(results);
+		ResultsMessage rm = new ResultsMessage();
+		rm.setResults(new List<?>[] {Arrays.asList(0), Arrays.asList(0), Arrays.asList(0)});
+		rm.setUpdateResult(true);
+		results.getResultsReceiver().receiveResults(rm);
+		Mockito.stub(conn.getDQP()).toReturn(dqp);
+		
+		// some update SQL
+		String sqlCommand = "delete from table where col=?"; //$NON-NLS-1$
+		TestableMMPreparedStatement statement = (TestableMMPreparedStatement) getMMPreparedStatement(conn, sqlCommand);
+
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(3);
+		// Add some batches and their parameter values
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(1) } ) ) );
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(2) } ) ) );
+		statement.setInt(1, new Integer(2));
+		statement.addBatch();
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(3) } ) ) );
+		statement.setInt(1, new Integer(3));
+		statement.addBatch();
+		
+		// execute the batch and verify that it matches our dummy results 
+		// message set earlier
+		assertTrue(Arrays.equals(new int[] {0, 0, 0}, statement.executeBatch()));
+		
+		// Now verify the statement's RequestMessage is what we expect 
+		assertEquals("Command does not match", sqlCommand, statement.requestMessage.getCommandString()); //$NON-NLS-1$
+		assertEquals("Parameter values do not match", expectedParameterValues, statement.requestMessage.getParameterValues()); //$NON-NLS-1$
+		assertTrue("RequestMessage.isBatchedUpdate should be true", statement.requestMessage.isBatchedUpdate()); //$NON-NLS-1$
+		assertFalse("RequestMessage.isCallableStatement should be false", statement.requestMessage.isCallableStatement()); //$NON-NLS-1$
+		assertTrue("RequestMessage.isPreparedStatement should be true", statement.requestMessage.isPreparedStatement()); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Verify that the <code>clearBatch()</code> method of 
+	 * <code>MMPreparedStatement</code> is clearing the list of batched 
+	 * commands.
+	 * <p>
+	 * This is done by first adding command parameter values to the batch and 
+	 * then invoking the <code>clearBatch()</code> method.
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testClearBatch() throws Exception {
+		PreparedStatementImpl statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+		// Add some stuff
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		statement.setInt(1, new Integer(2));
+		statement.addBatch();
+		// Make sure something is really there
+		assertTrue("MMPreparedStatement.ParameterValuesList should not be empty", statement.getParameterValuesList().size() > 0); //$NON-NLS-1$
+		// Now clear it
+		statement.clearBatch();
+		assertTrue("MMPreparedStatement.ParameterValuesList should be empty", statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+	}
+
+	/**
+	 * Adds additional batches of command parameter values to a prepared 
+	 * statement after a previous list has been cleared.
+	 * <p>
+	 * This is done by first adding command parameter values to the batch and 
+	 * then invoking the <code>clearBatch()</code> method.  Then a different 
+	 * set of command parameter values are added to the existing batch command.
+	 * <p>
+	 * The expected result is the command parameter list for the batches will 
+	 * only reflect what was added after <code>clearBatch()</code> was invoked.  
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testClearBatchAddBatch() throws Exception {
+		PreparedStatementImpl statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+		
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		statement.setInt(1, new Integer(2));
+		statement.addBatch();
+		// Make sure something is really there
+		assertTrue("MMPreparedStatement.ParameterValuesList should not be empty", statement.getParameterValuesList().size() > 0); //$NON-NLS-1$
+		// Now clear it
+		statement.clearBatch();
+		// Make sure it is empty now
+		assertTrue("MMPreparedStatement.ParameterValuesList should be empty", statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(1);
+		
+		// Now add something for validation 
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(5) } ) ) );
+		statement.setInt(1, new Integer(5));
+		statement.addBatch();
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+	}
+
+	/**
+	 * Test the <code>addBatch()</code> method of <code>MMPreparedStatement</code> 
+	 * to verify that the command parameter values of the batch are added to the 
+	 * command parameter values list.
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testAddBatch() throws Exception {
+		PreparedStatementImpl statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(1);
+		
+		// First we add a single batch 
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(1) } ) ) );
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+
+		// Now add some more batches just for sanity sake
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(3) } ) ) );
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(5) } ) ) );
+		statement.setInt(1, new Integer(3));
+		statement.addBatch();
+		statement.setInt(1, new Integer(5));
+		statement.addBatch();
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+	}
+
+	/**
+	 * Test the <code>addBatch()</code> method of <code>MMPreparedStatement</code> 
+	 * using a batch with an empty parameter value list.  The test will verify 
+	 * no failures occur when there are no command parameter values defined 
+	 * when the <code>addBatch()</code> method is invoked.
+	 * <p>
+	 * It is valid to add an empty parameter value list to a batch list.
+	 * <p>
+	 * For example:
+	 * <p>
+	 * <code>PreparedStatement stmt = conn.prepareStatement(sql);<br \>
+	 *  stmt.addBatch();<br \>
+	 *  stmt.addBatch();<br \>
+	 *  stmt.executeBatch();</code>
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testAddBatchNoParameterValues() throws Exception {
+		PreparedStatementImpl statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+		
+		// This will hold our expected values list
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(1);
+		
+		// First batch has an empty parameter value list
+		expectedParameterValues.add( new ArrayList<Object>(Collections.emptyList()) );
+
+		// No values have been set  so we are adding a batch with an empty 
+		// parameter value list
+		statement.addBatch();
+
+		// Second batch contains a parameter value list
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(1) } ) ) );
+
+		// We now are adding a batch that does have parameter values
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+
+		// Check to see if our statement contains our expected parameter value list
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+	}
+
+	/**
+	 * A helper method to get an <code>MMPreparedStatement</code> that can be 
+	 * used for simple test cases.
+	 * <p>
+	 * The returned value is an instance of <code>TestableMMPreparedStatement</code>
+	 * <p>
+	 * This method invokes <code>getMMPreparedStatement(final MMConnection conn, 
+	 * final String sql)</code> with a fake connection object constructed by 
+	 * <code>Mockito</code>.
+	 *   
+	 * @param sql the query for the prepared statement
+	 * @return an instance of TestableMMPreparedStatement
+	 * @throws SQLException
+	 */
+	protected PreparedStatementImpl getMMPreparedStatement(final String sql) throws SQLException {
+		ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+		ServerConnection serverConn = Mockito.mock(ServerConnection.class);
+		LogonResult logonResult = Mockito.mock(LogonResult.class);
+		
+		Mockito.stub(conn.getServerConnection()).toReturn(serverConn);
+		Mockito.stub(serverConn.getLogonResult()).toReturn(logonResult);
+		Mockito.stub(logonResult.getTimeZone()).toReturn(TimeZone.getDefault());
+
+		return getMMPreparedStatement(conn, sql);
+	}
+	
+	/**
+	 * A helper method to get an <code>MMPreparedStatement</code> that can be 
+	 * used for simple test cases.
+	 * <p>
+	 * The returned value is an instance of <code>TestableMMPreparedStatement</code>
+	 * <p>
+	 * <code>conn</code> should be a valid instance of <code>MMConnection</code> 
+	 * or this method will fail.
+	 * 
+	 * @param conn an instance of <code>MMConnection</code>
+	 * @param sql the query for the prepared statement
+	 * @return an instance of TestableMMPreparedStatement
+	 * @throws SQLException
+	 */
+	protected PreparedStatementImpl getMMPreparedStatement(final ConnectionImpl conn, final String sql) throws SQLException {
+		TestableMMPreparedStatement statement = new TestableMMPreparedStatement(conn, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+		
+		// Make sure everything is empty on start
+		assertTrue("MMPreparedStatement.ParameterValuesList should be empty", statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+		assertTrue("MMPreparedStatement.ParameterValues should be empty", statement.getParameterValues().size() == 0); //$NON-NLS-1$
+
+		return statement;
+	}
+	
+	/**
+	 * Represents an extension to <code>MMPreparedStatement</code> that 
+	 * gives access to the <code>RequestMessage</code> that is passed 
+	 * around inside <code>MMPreparedStatement</code>. 
+	 * <p>
+	 * This extension simply adds a field named <code>requestMessage</code> 
+	 * which is <code>public</code>.  This field gets set when the <code>protected</code>
+	 * method <code>createRequestMessage()</code> is called.
+	 * <p>
+	 * This extension also overrides <code>RequestMessage createRequestMessage(String[] commands,
+	 *			boolean isBatchedCommand, Boolean requiresResultSet)</code> so that 
+	 * reference to the created <code>RequestMessage</code> can be retained in 
+	 * the field <code>requestMessage</code>. 
+	 */
+	class TestableMMPreparedStatement extends PreparedStatementImpl {
+		/**
+		 * Contains a reference to the <code>RequestMessage</code> created by 
+		 * a call to <code>createRequestMessage(String[] commands, 
+		 * boolean isBatchedCommand, Boolean requiresResultSet)</code>.  This
+		 * will allow easy access to the prepared statement's request message 
+		 * generated by a call to one of the statement's execute methods.
+		 */
+		public RequestMessage requestMessage;
+		@Override
+		protected RequestMessage createRequestMessage(String[] commands,
+				boolean isBatchedCommand, ResultsMode resultsMode) {
+			this.requestMessage = super
+					.createRequestMessage(commands, isBatchedCommand, resultsMode);
+			return this.requestMessage;
+		}
+
+		public TestableMMPreparedStatement(ConnectionImpl connection,
+				String sql, int resultSetType, int resultSetConcurrency)
+				throws SQLException {
+			super(connection, sql, resultSetType, resultSetConcurrency);
+		}
+		
+	}
+
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMResultSet.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,753 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Test;
+import org.teiid.client.DQP;
+import org.teiid.client.ResultsMessage;
+
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+
+public class TestMMResultSet {
+
+    /** test next() without walking through */
+    @Test public void testNext1() throws SQLException {  
+        ResultSet cs =  helpExecuteQuery();
+        assertEquals(" Actual doesn't match with expected. ", new Integer(0), new Integer(cs.getRow())); //$NON-NLS-1$
+        cs.close();       
+    } 
+    
+    /** test next() with walking through all the rows and compare records */
+    @Test public void testNext2() throws SQLException {  
+        List[] expected = TestAllResultsImpl.exampleResults1(1000);
+        ResultSetImpl cs =  helpExecuteQuery();
+
+        int i=0;
+        while(cs.next()) { 
+           assertEquals(" Actual doesn't match with expected. ", expected[i], cs.getCurrentRecord()); //$NON-NLS-1$
+           i++;
+        }
+
+        cs.close();
+    } 
+
+    /** test with LargeA -- only work with real model rather than fake metadata*/
+    
+    // Note for all the following: processor batch size is 100,
+    // so some of these tests check what happens when the client 
+    // fetch size is above, the same, or below it
+    public static final int PROC_BATCH_SIZE = 100;
+    
+    /** Test stability when next() is called beyond the rowcount. */
+    @Test public void testNextBeyondEnd_fetchEqualsCount() throws Exception {
+        helpTestNextBeyondResultSet(1000, 1000);
+    }
+
+    /** Test stability when next() is called beyond the rowcount. */
+    @Test public void testNextBeyondEnd_fetchLessThanCount() throws Exception {
+        helpTestNextBeyondResultSet(100, 1000);
+    }
+    
+    /** Test stability when next() is called beyond the rowcount with one more row. */
+    @Test public void testNextBeyondEnd_fetchLessThanCount1() throws Exception {
+        helpTestNextBeyondResultSet(100, 101);
+    }
+
+    /** Test stability when next() is called beyond the rowcount. */
+    @Test public void testNextBeyondEnd_fetchLessThanCountNonMultiple() throws Exception {
+        helpTestNextBeyondResultSet(120, 1000);
+    }
+
+    /** Test stability when next() is called beyond the rowcount. */
+    @Test public void testNextBeyondEnd_fetchGreaterThanCount() throws Exception {
+        helpTestNextBeyondResultSet(300, PROC_BATCH_SIZE);
+    }
+
+    /** Test stability when next() is called beyond the rowcount. */
+    @Test public void testNextBeyondEnd_fetchGreaterThanCountNonMultiple() throws Exception {
+        helpTestNextBeyondResultSet(310, PROC_BATCH_SIZE-50);
+    }
+
+    /** Test stability when next() is called beyond the rowcount. */
+    @Test public void testNextBeyondEnd_fetchGreaterThanCountNonMultiple2() throws Exception {
+        helpTestNextBeyondResultSet(300, PROC_BATCH_SIZE+10);
+    }
+    
+    /** Test that the returned results walks through all results if
+     * fetchSize &lt; rows &lt; proc batch size.
+     * Test for defect 11356
+     */
+    @Test public void testNextBeyondEnd_fetchLessThanCount_ResultsBetweenFetchAndProcBatch() throws Exception {
+        helpTestNextBeyondResultSet(30, PROC_BATCH_SIZE-25);
+    }
+
+    public void helpTestNextBeyondResultSet(int fetchSize, int numRows) throws Exception {
+        ResultSet cs = helpExecuteQuery(fetchSize, numRows, ResultSet.TYPE_SCROLL_INSENSITIVE);
+        try {
+            Object lastRowValue = null;
+            for (int rowNum = 1; rowNum <= numRows; rowNum++) {
+                assertEquals("Should return true before end cs.next()", true, cs.next()); //$NON-NLS-1$
+            }
+
+            lastRowValue = cs.getObject(1);               
+            
+            // Should just return false and leave cursor where it is 
+            for(int i=numRows+1; i<numRows+4; i++) {
+                assertEquals("Should return false when going past the end: " + i, false, cs.next()); //$NON-NLS-1$
+                assertEquals("Is after last should be true: " + i, true, cs.isAfterLast()); //$NON-NLS-1$
+            }
+            
+            // Should still be just after last row
+            cs.previous();
+            assertEquals("Is last should be true", true, cs.isLast()); //$NON-NLS-1$
+            assertEquals("Not on last row", lastRowValue, cs.getObject(1));              //$NON-NLS-1$
+            
+        } finally {
+            cs.close();
+        }
+    }
+    
+    /** test both next() and previous() -- when result set scroll in bidirection */
+    @Test public void testBidirection() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        assertNotNull(cs);
+        cs.absolute(290);
+        assertEquals(" Actual value doesn't match with expected one.", new Integer(290), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+        cs.next();
+        assertEquals(" Actual value doesn't match with expected one.", new Integer(291), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+        cs.next();
+        assertEquals(" Actual value doesn't match with expected one.", new Integer(292), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+        cs.previous();
+        assertEquals(" Actual value doesn't match with expected one.", new Integer(291), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+        cs.next();
+        assertEquals(" Actual value doesn't match with expected one.", new Integer(292), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+        cs.close();
+    }
+            
+    /** test hasNext() without walking through any row */
+    @Test public void testHasNext1() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        assertEquals(" hasNext() doesn't match expected value. ", true, cs.hasNext()); //$NON-NLS-1$
+        cs.close();          
+    }
+
+    /** test hasNext() with blocking for the Next batch -- triggering point */
+    @Test public void testHasNext2() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.absolute(100);
+        assertEquals(" hasNext() doesn't match expected value. ", true, cs.hasNext());  //$NON-NLS-1$
+        cs.close();       
+    }
+    
+    /** test hasNext() with nextBatch!=null -- short response */
+    @Test public void testHasNext3() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        int i = 0;
+        while (cs.next()) {
+            if (i == 289) {
+                break;
+            }
+            i++;
+        }
+        assertEquals(" hasNext() doesn't match expected value. ", true, cs.hasNext()); //$NON-NLS-1$
+        cs.close();         
+    }
+    
+    /** at the end of all batches */
+    @Test public void testHasNext4() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.absolute(1000);
+        assertTrue(!cs.hasNext());
+        cs.close();       
+    }
+    
+    /** walk all way through from the end back to first row */
+    @Test public void testPrevious1() throws SQLException {  
+        ResultSetImpl cs = helpExecuteQuery();
+        List[] expected = TestAllResultsImpl.exampleResults1(1000);
+        while(cs.next()) {
+            //System.out.println(" rs.next == " + cs.getCurrentRecord());
+        }
+        // cursor is after the last row. getRow() should return 0 when not on a valid row
+        assertEquals(" current row doesn't match expected value. ", 0, cs.getRow()); //$NON-NLS-1$
+
+        int i= 1000;
+        while (cs.previous()) {
+            //System.out.println(" rs.previous == " + cs.getCurrentRecord());
+            assertEquals(" Actual doesn't match with expected. ", expected[i-1], cs.getCurrentRecord()); //$NON-NLS-1$
+            i--;
+        }
+        assertEquals(" current row doesn't match expected value. ", 0, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    } 
+    
+    /** test the previous in the middle of a batch */
+    @Test public void testPrevious2() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.absolute(290);
+
+        // cursor is at the row of 289 now
+        assertTrue(cs.previous());
+        assertEquals(" current row doesn't match expected value. ", 289, cs.getRow()); //$NON-NLS-1$
+        cs.close();     
+    }
+
+    /** walk all way through from the end back to first row */
+    @Test public void testPrevious3() throws Exception {  
+        //large batch size
+        ResultSetImpl cs = helpExecuteQuery(600, 10000, ResultSet.TYPE_SCROLL_INSENSITIVE);
+        List[] expected = TestAllResultsImpl.exampleResults1(10000);
+        while(cs.next()) {
+        }
+        // cursor is after the last row. getRow() should return 0 when not on a valid row
+        assertEquals(" current row doesn't match expected value. ", 0, cs.getRow()); //$NON-NLS-1$
+
+        int i= 10000;
+        while (cs.previous()) {
+            //System.out.println(" rs.previous == " + cs.getCurrentRecord());
+            assertEquals(" Actual doesn't match with expected. ", expected[i-1], cs.getCurrentRecord()); //$NON-NLS-1$
+            i--;
+        }
+        assertEquals(" current row doesn't match expected value. ", 0, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    } 
+    
+    /** walk all way through from the end back to first row */
+    @Test public void testPrevious4() throws Exception {  
+        //small batch size
+        ResultSetImpl cs = helpExecuteQuery(50, 1000, ResultSet.TYPE_SCROLL_INSENSITIVE);
+        List[] expected = TestAllResultsImpl.exampleResults1(1000);
+        while(cs.next()) {
+            //System.out.println(" rs.next == " + cs.getCurrentRecord());
+        }
+        // cursor is after the last row. getRow() should return 0 when not on a valid row
+        assertEquals(" current row doesn't match expected value. ", 0, cs.getRow()); //$NON-NLS-1$
+
+        int i= 1000;
+        while (cs.previous()) {
+            //System.out.println(" rs.previous == " + cs.getCurrentRecord());
+            assertEquals(" Actual doesn't match with expected. ", expected[i-1], cs.getCurrentRecord()); //$NON-NLS-1$
+            i--;
+        }
+        assertEquals(" current row doesn't match expected value. ", 0, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    } 
+    
+    /** test rare case that cursor change direction */
+    @Test public void testChangeDirection() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.absolute(291);
+        cs.previous();
+        
+        assertEquals(" current row doesn't match expected value. ", 290, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    }
+             
+    @Test public void testIsFirst() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.next();
+        assertTrue(cs.isFirst());
+        cs.close();
+    }
+
+    /** test cursor is in the middle of all batches */
+    @Test public void testIsLast1() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        cs.next();
+        assertTrue(!cs.isLast());
+        cs.close();     
+    }
+
+    /** test cursor at the triggering point -- blocking case*/
+    @Test public void testIsLast2() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        
+        int i = 0;
+        while (cs.next()) {
+            if (i == 99) {
+                break;
+            }
+            i++;
+        }
+        
+        assertTrue(!cs.isLast());
+        cs.close();      
+    }
+
+    /** test cursor at the last row of all batches */
+    @Test public void testIsLast3() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.absolute(1000);
+        assertTrue(cs.isLast());
+        cs.close();
+    }        
+ 
+    @Test public void testIsBeforeFirst() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        assertTrue(cs.isBeforeFirst());
+        cs.close();        
+    }
+
+    @Test public void testBeforeFirst() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row 1
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 1, cs.getRow()); //$NON-NLS-1$
+        
+        // move back to before first row
+        cs.beforeFirst();
+        assertTrue(cs.isBeforeFirst());
+        cs.close();           
+    }
+
+    @Test public void testFirst() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row #2
+        cs.next();
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 2, cs.getRow()); //$NON-NLS-1$
+        
+        // move back to the 1st row
+        cs.first();
+        assertEquals(" Current row number doesn't match with expected one.", 1, cs.getRow()); //$NON-NLS-1$
+        cs.close();           
+    }
+
+    @Test public void testAfterLast() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        cs.afterLast();
+        assertTrue(cs.isAfterLast());   
+        cs.close();
+    }
+    
+    /** right after the last row */
+    @Test public void testIsAfterLast1() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        cs.absolute(1000);
+        cs.next();
+        assertTrue(cs.isAfterLast());
+        cs.close();
+    }
+
+    /** right before the first */
+    @Test public void testIsAfterLast2() throws Exception {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        assertTrue(!cs.isAfterLast());
+        cs.close();
+    }
+      
+    /** absolute with cursor movement backward in the same batch -- absolute(positive) */
+    @Test public void testAbsolute1() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row #2
+        cs.next();
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 2, cs.getRow()); //$NON-NLS-1$
+        
+        // move back to the 1st row
+        cs.absolute(1);
+        assertEquals(" Current row number doesn't match with expected one.", 1, cs.getRow()); //$NON-NLS-1$
+        cs.close();          
+    }
+
+    /** absolute with cursor movement forward in the same batch -- absolute(positive) */ 
+    @Test public void testAbsolute2() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row #2
+        cs.next();
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 2, cs.getRow()); //$NON-NLS-1$
+        
+        // move back to the 1st row
+        cs.absolute(3);
+        assertEquals(" Current row number doesn't match with expected one.", 3, cs.getRow()); //$NON-NLS-1$
+        cs.close();          
+    }
+
+    /** absolute with cursor movement forward -- absolute(positive) -- blocking */
+    @Test public void testAbsolute3() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row #2
+        cs.next();
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 2, cs.getRow()); //$NON-NLS-1$
+        
+        // move to row #100 -- blocking 
+        cs.absolute(100);
+        assertEquals(" Current row number doesn't match with expected one.", 100, cs.getRow()); //$NON-NLS-1$
+        cs.close();          
+    }
+
+    /** absolute with cursor movement forward -- absolute(positive) -- triggering point */
+    @Test public void testAbsolute4() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row #2
+        cs.next();
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 2, cs.getRow()); //$NON-NLS-1$
+        
+        // move to row #200 -- new batch 
+        cs.absolute(200);
+        assertEquals(" Current row number doesn't match with expected one.", 200, cs.getRow()); //$NON-NLS-1$
+        cs.close();        
+    }
+    
+    /** absolute with cursor movement back in the same batch -- absolute(negative) */ 
+    @Test public void testAbsolute5() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        
+        // move to row #2
+        cs.next();
+        cs.next();
+        assertEquals(" Current row number doesn't match with expected one.", 2, cs.getRow()); //$NON-NLS-1$
+        
+        // move back to the 1st row
+        cs.absolute(-1);
+        assertEquals(" Current row number doesn't match with expected one.", 1000, cs.getRow());           //$NON-NLS-1$
+        cs.close();
+    }
+
+    /** absolute after last row */ 
+    @Test public void testAbsolute6() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+        cs.absolute(1005);
+        // Cursor should be after last row. getRow() should return 0 because
+        // cursor is not on a valid row
+        assertEquals(" Current row number doesn't match with expected one.", 0, cs.getRow());           //$NON-NLS-1$
+        cs.close();
+    }
+               
+    /** relative(positive) -- forward to another batch */           
+    @Test public void testRelative1() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+
+        // move to the row #3
+        cs.absolute(3);
+        assertEquals(" Current row number doesn't match with expected one.", 3, cs.getRow()); //$NON-NLS-1$
+        
+        // move to the row #140
+        cs.relative(137);
+        assertEquals(" Current row number doesn't match with expected one.", 140, cs.getRow()); //$NON-NLS-1$
+        cs.close();       
+    }
+
+    /** relative(negative) -- backward to another batch */          
+    @Test public void testRelative2() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+
+        // move to the row #137
+        cs.absolute(137);
+        assertEquals(" Current row number doesn't match with expected one.", 137, cs.getRow()); //$NON-NLS-1$
+        
+        // move to the row #4
+        cs.relative(-133);
+        assertEquals(" Current row number doesn't match with expected one.", 4, cs.getRow()); //$NON-NLS-1$
+        cs.close();      
+    }  
+
+    /** relative(negative) -- backward to triggering point or blocking batch */          
+    @Test public void testRelative3() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+
+        // move to the row #137
+        cs.absolute(137);
+        assertEquals(" Current row number doesn't match with expected one.", 137, cs.getRow()); //$NON-NLS-1$
+        
+        // move to the row #100
+        cs.relative(-37);
+        assertEquals(" Current row number doesn't match with expected one.", 100, cs.getRow()); //$NON-NLS-1$
+        cs.close();      
+    }  
+                           
+    /** relative(negative) -- backward to triggering point or blocking batch */          
+    @Test public void testRelative4() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery(); 
+
+        // move to the row #237 in the third batch, so that the fourth batch has been requested when we switch direction
+        cs.absolute(237);
+        assertEquals(" Current row number doesn't match with expected one.", 237, cs.getRow()); //$NON-NLS-1$
+        
+        // move to the row #37
+        cs.relative(-200);
+        assertEquals(" Current row number doesn't match with expected one.", 37, cs.getRow()); //$NON-NLS-1$
+        cs.close();      
+    }  
+                           
+    /** in the first fetched batch */                             
+    @Test public void testGetRow1() throws SQLException {
+        ResultSet cs =  helpExecuteQuery();
+
+        int i = 0;
+        while (cs.next()) {
+            if (i == 102) {
+                break;
+            }
+            i++;
+        }
+        
+        assertEquals(" Current row number doesn't match with expected one.", i+1, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    }
+
+    /** in the first batch */                             
+    @Test public void testGetRow2() throws SQLException {
+        ResultSet cs =  helpExecuteQuery();
+
+        cs.next();        
+        assertEquals(" Current row number doesn't match with expected one.", 1, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    }
+
+    /** in the triggering point -- blocking  */                             
+    @Test public void testGetRow3() throws SQLException {
+        ResultSet cs =  helpExecuteQuery();
+        int i = 0;
+        while (cs.next()) {
+            if (i == 99) {
+                break;
+            }
+            i++;
+        }      
+        assertEquals(" Current row number doesn't match with expected one.", 100, cs.getRow()); //$NON-NLS-1$
+        cs.close();
+    }
+            
+    @Test public void testGetCurrentRecord() throws SQLException {
+        ResultSet cs =  helpExecuteQuery();
+        cs.absolute(103);
+        assertEquals(" Current record doesn't match with expected one.", new Integer(103), ((ResultSetImpl)cs).getCurrentRecord().get(0));                 //$NON-NLS-1$
+        cs.close();
+    }
+
+    /** test close() without walking through any of the record*/
+    @Test public void testClose() throws SQLException {  
+        ResultSetImpl cs =  helpExecuteQuery();
+        assertEquals(" Actual doesn't match with expected. ", new Integer(0), new Integer(cs.getRow())); //$NON-NLS-1$
+        cs.close();          
+    } 
+    
+    /** test basic results-related metadata */
+    @Test public void testGetMetaData() throws SQLException {    
+        ResultSetImpl cs =  helpExecuteQuery();
+        
+        // check result set metadata
+        // expected column info.
+        List columnName = getBQTRSMetaData1a();
+        List columnType = getBQTRSMetaData1b();
+        List columnTypeName = getBQTRSMetaData1c();
+
+        ResultSetMetaData rm = cs.getMetaData();
+        assertNotNull(rm);
+            
+        for (int j = 1; j <= rm.getColumnCount(); j++) {  
+            assertEquals(" Actual doesn't match with expected. ", columnName.get(j-1), rm.getColumnName(j)); //$NON-NLS-1$
+            assertEquals(" Actual doesn't match with expected. ", columnType.get(j-1), new Integer(rm.getColumnType(j))); //$NON-NLS-1$
+            assertEquals(" Actual doesn't match with expected. ", columnTypeName.get(j-1), rm.getColumnTypeName(j)); //$NON-NLS-1$
+        }
+        
+        cs.close();     
+    }
+
+    @Test public void testFindColumn() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        ResultSetMetaData rm = cs.getMetaData();
+        assertNotNull(rm);
+        //assertEquals(" Actual columnName doesn't match with expected. ", 1, cs.findColumn("BQT1.MediumA.IntKey"));            
+        assertEquals(" Actual columnName doesn't match with expected. ", 1, cs.findColumn("IntKey"));                       //$NON-NLS-1$ //$NON-NLS-2$
+        cs.close();             
+    }
+    
+    @Test public void testFindNonExistentColumn() throws SQLException {
+        ResultSet rs = helpExecuteQuery();
+        rs.next();
+        try {
+            rs.findColumn("BOGUS"); //$NON-NLS-1$
+        } catch(SQLException e) {
+        }
+        
+        try { 
+            rs.getObject("BOGUS"); //$NON-NLS-1$
+        } catch(SQLException e) {
+        }
+        rs.close();             
+    }
+    
+    @Test public void testGetStatement() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();     
+        assertNotNull(cs.getStatement());
+        cs.close();
+    }
+        
+    @Test public void testGetPlanDescription() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        assertNotNull(cs);
+        
+        assertNull((cs.getStatement()).getPlanDescription());
+        cs.close();
+    }
+    
+    /** getObject(String) */ 
+    @Test public void testGetObject2() throws SQLException {
+        ResultSet cs =  helpExecuteQuery();
+        
+        // move to the 1st row
+        cs.next();  
+        assertEquals(" Actual value doesn't match with expected. ", new Integer(1), cs.getObject("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        cs.close();   
+    }
+
+    @Test public void testGetWarnings() throws SQLException {
+        ResultSet cs =  helpExecuteQuery();
+        assertNull(cs.getWarnings());
+        cs.close();
+    }
+    
+    @Test public void testGetCursorName() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        assertNull(cs.getCursorName()); 
+        cs.close();
+    }
+    
+    @Test public void testAllGetters() throws SQLException {
+        ResultSetImpl cs =  helpExecuteQuery();
+        cs.next();
+        assertEquals(" Actual value of getInt() doesn't match with expected one. ", 1, cs.getInt("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals(" Actual value of getString() doesn't match with expected one. ", "1", cs.getString("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        
+        // Add these back when the MediumA has all those columns 
+        assertEquals(" Actual value of getFloat() doesn't match with expected one. ", new Float(1), new Float(cs.getFloat("IntKey"))); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals(" Actual value of getLong() doesn't match with expected one. ", 1, cs.getLong("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals(" Actual value of getDouble() doesn't match with expected one. ", new Double(1), new Double(cs.getDouble("IntKey"))); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals(" Actual value of getByte() doesn't match with expected one. ", (byte)1, cs.getByte("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    /** test wasNull() for ResultSet, this result actually is not a cursor result, but AllResults here. */
+    @Test public void testWasNull() throws SQLException {
+        ResultSet cs = helpExecuteQuery();
+        cs.next();
+        assertNotNull(cs.getObject("IntKey")); //$NON-NLS-1$
+        assertFalse(cs.wasNull());
+    }
+ 
+    @Test public void testForwardOnly() throws Exception {
+        ResultSetImpl cs = helpExecuteQuery(400, 1000, ResultSet.TYPE_FORWARD_ONLY);
+        
+        while (cs.next()) {
+            cs.getObject(1);
+        }
+        
+        assertTrue(cs.isAfterLast());
+        cs.close();      
+    }
+    
+    @Test public void testOutputParameter() throws Exception {
+        StatementImpl statement = createMockStatement(ResultSet.TYPE_FORWARD_ONLY);
+        ResultsMessage resultsMsg = new ResultsMessage();
+        resultsMsg.setResults(new List<?>[] {Arrays.asList(1, null, null), Arrays.asList(null, 2, 3)});
+        resultsMsg.setLastRow(2);
+        resultsMsg.setFirstRow(1);
+        resultsMsg.setFinalRow(2);
+        resultsMsg.setColumnNames(new String[] {"x", "out1", "out2"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        resultsMsg.setDataTypes(new String[] {"integer", "integer", "integer"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        ResultSetImpl cs = new ResultSetImpl(resultsMsg, statement, null, 2);
+        
+        int count = 0;
+        while (cs.next()) {
+            cs.getObject(1);
+            count++;
+        }
+        assertEquals(1, count);
+        assertTrue(cs.isAfterLast());
+        assertEquals(2, cs.getOutputParamValue(2));
+        assertEquals(3, cs.getOutputParamValue(3));
+    }
+         
+    /////////////////////// Helper Method ///////////////////
+
+    private ResultSetImpl helpExecuteQuery() {
+        try {
+			return helpExecuteQuery(400, 1000, ResultSet.TYPE_SCROLL_INSENSITIVE);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+    }
+    
+    private ResultSetImpl helpExecuteQuery(int fetchSize, int totalResults, int cursorType) throws SQLException, MetaMatrixProcessingException, InterruptedException, ExecutionException, TimeoutException {
+        StatementImpl statement = createMockStatement(cursorType);
+		return TestAllResultsImpl.helpTestBatching(statement, fetchSize, Math.min(fetchSize, totalResults), totalResults);
+    }
+
+	static StatementImpl createMockStatement(int cursorType) throws SQLException {
+		StatementImpl statement = mock(StatementImpl.class);
+		stub(statement.getDQP()).toReturn(mock(DQP.class));
+		stub(statement.getResultSetType()).toReturn(cursorType);
+		TimeZone tz = TimeZone.getTimeZone("GMT-06:00"); //$NON-NLS-1$
+		TimeZone serverTz = TimeZone.getTimeZone("GMT-05:00"); //$NON-NLS-1$
+		stub(statement.getDefaultCalendar()).toReturn(Calendar.getInstance(tz));
+		stub(statement.getServerTimeZone()).toReturn(serverTz);
+		return statement;
+	}
+
+    ////////////////////////Expected Results////////////////
+    /** column name */
+    private List getBQTRSMetaData1a() {
+        List results = new ArrayList();
+        results.add("IntKey"); //$NON-NLS-1$
+        return results;   
+    }
+
+    /** column type */
+    private List getBQTRSMetaData1b() {
+        List results = new ArrayList();
+        results.add(new Integer(Types.INTEGER));
+        return results;   
+    }
+
+    /** column type name*/
+    private List getBQTRSMetaData1c() {
+        List results = new ArrayList();
+        results.add("integer"); //$NON-NLS-1$
+        return results;   
+    }               
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMSQLException.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,235 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.NoRouteToHostException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.sql.SQLException;
+
+import org.teiid.jdbc.TeiidSQLException;
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+
+import junit.framework.TestCase;
+
+import com.metamatrix.api.exception.MetaMatrixException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.api.exception.query.ProcedureErrorInstructionException;
+import com.metamatrix.core.MetaMatrixCoreException;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+
+public class TestMMSQLException extends TestCase {
+  
+	/*
+	 * Test method for 'com.metamatrix.jdbc.MMSQLException.MMSQLException()'
+	 */
+	public void testMMSQLException() {
+		TeiidSQLException e = new TeiidSQLException();
+		String sqlState = e.getSQLState();
+		Throwable cause = e.getCause();
+		int errorCode = e.getErrorCode();
+		Throwable nestedException = e.getCause();
+		SQLException nextException = e.getNextException();
+
+		assertTrue(
+				"Expected MMSQLException.getSQLState() to return <null> but got \"" //$NON-NLS-1$
+						+ sqlState + "\" instead.", sqlState == null); //$NON-NLS-1$
+		assertTrue(
+				"Expected MMSQLException.getCause() to return <null> but got [" //$NON-NLS-1$
+						+ (cause != null ? cause.getClass().getName()
+								: "<unknown>") + "] instead.", cause == null); //$NON-NLS-1$ //$NON-NLS-2$
+		assertTrue(
+				"Expected MMSQLException.getErrorCode() to return [0] but got [" //$NON-NLS-1$
+						+ errorCode + "] instead.", errorCode == 0); //$NON-NLS-1$
+		assertTrue(
+				"Expected MMSQLException.getNestedException() to return <null> but got [" //$NON-NLS-1$
+						+ (nestedException != null ? nestedException.getClass()
+								.getName() : "<unknown>") + "] instead.", //$NON-NLS-1$ //$NON-NLS-2$
+				nestedException == null);
+		assertTrue(
+				"Expected MMSQLException.getNextException() to return <null> but got a SQLException with message \"" //$NON-NLS-1$
+						+ (nextException != null ? nextException.getMessage()
+								: "") + "\" instead.", nextException == null); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/*
+	 * Test method for 'com.metamatrix.jdbc.MMSQLException.create(Throwable)'
+	 * 
+	 * Tests various simple exceptions to see if the expected SQLState is
+	 * returend.
+	 */
+	public void testCreateThrowable_01() {
+		testCreateThrowable(new CommunicationException(
+				"A test MM Communication Exception"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+		testCreateThrowable(
+				new ConnectException("A test connection attempt exception"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+		testCreateThrowable(
+				new ConnectionException("A test MM Connection Exception"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+		testCreateThrowable(new IOException(
+				"A test Generic java.io.IOException"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+		testCreateThrowable(
+				new MalformedURLException(
+						"A test java.net.MalformedURLException"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+		testCreateThrowable(new MetaMatrixCoreException(
+				"A test Generic MM Core Exception"), SQLStates.DEFAULT); //$NON-NLS-1$
+		testCreateThrowable(new MetaMatrixException("A test MM Exception"), //$NON-NLS-1$
+				SQLStates.DEFAULT);
+		testCreateThrowable(new MetaMatrixProcessingException(
+				"A test Generic MM Query Processing Exception"), //$NON-NLS-1$
+				SQLStates.USAGE_ERROR);
+		testCreateThrowable(new MetaMatrixRuntimeException(
+				"A test MM Runtime Exception"), SQLStates.DEFAULT); //$NON-NLS-1$
+		testCreateThrowable(new TeiidSQLException(
+				"A test Generic MM SQL Exception"), SQLStates.DEFAULT); //$NON-NLS-1$
+		testCreateThrowable(
+				new NoRouteToHostException(
+						"A test java.net.NoRouteToHostException"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+		testCreateThrowable(new NullPointerException("A test NPE"), //$NON-NLS-1$
+				SQLStates.DEFAULT);
+		testCreateThrowable(new ProcedureErrorInstructionException(
+				"A test SQL Procedure Error exception"), //$NON-NLS-1$
+				SQLStates.VIRTUAL_PROCEDURE_ERROR);
+		testCreateThrowable(new SocketTimeoutException(
+				"A test socket timeout exception"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+		testCreateThrowable(
+				new UnknownHostException("A test connection attempt exception"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+	}
+
+	/*
+	 * Test method for 'com.metamatrix.jdbc.MMSQLException.create(Throwable)'
+	 * 
+	 * Tests various nested exceptions to see if the expected SQLState is
+	 * returend.
+	 */
+	public void testCreateThrowable_02() {
+		testCreateThrowable(
+				new CommunicationException(new ConnectException(
+						"A test java.net.ConnectException"), //$NON-NLS-1$
+						"Test Communication Exception with a ConnectException in it"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+		testCreateThrowable(new CommunicationException(new SocketException(
+				"A test java.net.SocketException"), //$NON-NLS-1$
+				"Test Communication Exception with a SocketException in it"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+		testCreateThrowable(
+				new MetaMatrixException(new SocketTimeoutException(
+						"A test java.net.SocketTimeoutException"), //$NON-NLS-1$
+						"Test MetaMatrixException with a SocketTimeoutException in it"), //$NON-NLS-1$
+				SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+	}
+    
+    public void testCreateThrowable3() {
+        TeiidSQLException e = testCreateThrowable(
+                            new MetaMatrixCoreException(
+                                    new MetaMatrixRuntimeException(
+                                            new SocketTimeoutException(
+                                                    "A test MM Invalid Session Exception"), //$NON-NLS-1$
+                                            "Test MetaMatrixRuntimeException with a InvalidSessionException in it"), //$NON-NLS-1$
+                                    "Test MM Core Exception with an MM Runtime Exception in it and an InvalidSessionException nested within"), //$NON-NLS-1$
+                            SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+        
+        //test to ensure that wrapping mmsqlexceptions works
+        TeiidSQLException e1 = TeiidSQLException.create(e, "new message"); //$NON-NLS-1$
+        assertEquals("new message", e1.getMessage()); //$NON-NLS-1$
+        testCreateThrowable(((TeiidSQLException)e1.getCause()).getCause(), SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+    }
+
+	/*
+	 * Helper method to test SQLState and general MMSQLException validation
+	 */
+	private TeiidSQLException testCreateThrowable(Throwable ecause, String esqlState) {
+		TeiidSQLException e = TeiidSQLException.create(ecause);
+		if (ecause.getClass() == TeiidSQLException.class) {
+            ecause = null;
+		}
+		String sqlState = e.getSQLState();
+		Throwable cause = e.getCause();
+		int errorCode = e.getErrorCode();
+		Throwable nestedException = e.getCause();
+		SQLException nextException = e.getNextException();
+
+		assertTrue("Expected MMSQLException.getSQLState() to return \"" //$NON-NLS-1$
+				+ esqlState + "\" but got \"" + sqlState + "\" instead.", //$NON-NLS-1$ //$NON-NLS-2$
+				sqlState.compareTo(esqlState) == 0);
+		assertTrue("Expected MMSQLException.getCause() to return [" //$NON-NLS-1$
+				+ (ecause != null ? ecause.getClass().getName() : "<null>") //$NON-NLS-1$
+				+ "] but got [" //$NON-NLS-1$
+				+ (cause != null ? cause.getClass().getName() : "<unknown>") //$NON-NLS-1$
+				+ "] instead.", cause == ecause); //$NON-NLS-1$
+		assertTrue(
+				"Expected MMSQLException.getErrorCode() to return [0] but got [" //$NON-NLS-1$
+						+ errorCode + "] instead.", errorCode == 0); //$NON-NLS-1$
+		assertTrue("Expected MMSQLException.getNestedException() to return [" //$NON-NLS-1$
+				+ (ecause != null ? ecause.getClass().getName() : "<null>") //$NON-NLS-1$
+				+ "] but got [" //$NON-NLS-1$
+				+ (nestedException != null ? nestedException.getClass()
+						.getName() : "<unknown>") + "] instead.", //$NON-NLS-1$ //$NON-NLS-2$
+				nestedException == ecause);
+		assertTrue(
+				"Expected MMSQLException.getNextException() to return <null> but got a SQLException with message \"" //$NON-NLS-1$
+						+ (nextException != null ? nextException.getMessage()
+								: "") + "\" instead.", nextException == null); //$NON-NLS-1$ //$NON-NLS-2$
+		return e;
+    }
+    
+    public void testCreate() {
+        TeiidSQLException exception = TeiidSQLException.create(new Exception());
+        
+        assertEquals(exception.getMessage(), Exception.class.getName());
+        assertNotNull(exception.getSQLState());
+        assertEquals(exception.getSQLState(), "38000"); //$NON-NLS-1$
+        
+        assertEquals(exception, TeiidSQLException.create(exception));
+    }
+    
+    public void testCreateFromSQLException() {
+        SQLException sqlexception = new SQLException("foo", "21"); //$NON-NLS-1$ //$NON-NLS-2$
+        
+        SQLException nested = new SQLException("bar"); //$NON-NLS-1$
+        
+        sqlexception.setNextException(nested);
+        
+        String message = "top level message"; //$NON-NLS-1$
+        
+        TeiidSQLException exception = TeiidSQLException.create(sqlexception, message);
+        
+        assertEquals(exception.getMessage(), message);
+        assertEquals(exception.getSQLState(), sqlexception.getSQLState());        
+        assertEquals(exception.getNextException().getMessage(), sqlexception.getMessage());
+        assertEquals(exception.getNextException().getNextException().getMessage(), nested.getMessage());
+    }
+
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMStatement.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.ResultSet;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.TeiidSQLException;
+import org.teiid.jdbc.StatementImpl;
+
+
+public class TestMMStatement {
+
+	@Test(expected=TeiidSQLException.class) public void testUpdateException() throws Exception {
+		StatementImpl statement = new StatementImpl(Mockito.mock(ConnectionImpl.class), ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+		statement.executeQuery("delete from table"); //$NON-NLS-1$
+	}
+	
+	@Test public void testBatchExecution() throws Exception {
+		ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+		DQP dqp = Mockito.mock(DQP.class);
+		ResultsFuture<ResultsMessage> results = new ResultsFuture<ResultsMessage>(); 
+		Mockito.stub(dqp.executeRequest(Mockito.anyLong(), (RequestMessage)Mockito.anyObject())).toReturn(results);
+		ResultsMessage rm = new ResultsMessage();
+		rm.setResults(new List<?>[] {Arrays.asList(1), Arrays.asList(2)});
+		rm.setUpdateResult(true);
+		results.getResultsReceiver().receiveResults(rm);
+		Mockito.stub(conn.getDQP()).toReturn(dqp);
+		StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+		statement.addBatch("delete from table"); //$NON-NLS-1$
+		statement.addBatch("delete from table1"); //$NON-NLS-1$
+		assertTrue(Arrays.equals(new int[] {1, 2}, statement.executeBatch()));
+	}
+	
+	@Test public void testSetStatement() throws Exception {
+		ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+		Properties p = new Properties();
+		Mockito.stub(conn.getConnectionProperties()).toReturn(p);
+		StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+		assertFalse(statement.execute("set foo = bar")); //$NON-NLS-1$
+		assertEquals("bar", p.get("foo")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMXAConnection.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.transaction.xa.XAResource;
+
+import org.teiid.client.xa.XidImpl;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.StatementImpl;
+import org.teiid.jdbc.XAConnectionImpl;
+
+import junit.framework.TestCase;
+
+
+
+public class TestMMXAConnection extends TestCase {
+	
+	public void testConnectionClose() throws Exception {
+
+		final ConnectionImpl mmConn = TestMMConnection.getMMConnection();
+
+		XAConnectionImpl xaConn = new XAConnectionImpl(new XAConnectionImpl.ConnectionSource() {
+			//## JDBC4.0-begin ##
+			@Override
+			//## JDBC4.0-end ##
+			public ConnectionImpl createConnection() throws SQLException {
+				return mmConn;
+			}
+		});
+		
+		Connection conn = xaConn.getConnection();
+		StatementImpl stmt = (StatementImpl)conn.createStatement();
+		conn.setAutoCommit(false);
+		conn.close();
+
+		assertTrue(stmt.isClosed());
+		assertTrue(conn.getAutoCommit());
+		
+		conn = xaConn.getConnection();
+		stmt = (StatementImpl)conn.createStatement();
+		XAResource resource = xaConn.getXAResource();
+		resource.start(new XidImpl(1, new byte[0], new byte[0]), XAResource.TMNOFLAGS);
+		conn.close();
+		
+		assertTrue(stmt.isClosed());
+		assertTrue(conn.getAutoCommit());
+	}
+
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestSocketProfile.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.teiid.net.TeiidURL;
+
+
+public class TestSocketProfile {
+    public String localhost = "localhost"; //$NON-NLS-1$
+    
+    /** Valid format of urls*/
+    @Test public void testAcceptsURL1()  throws Exception   {
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:jvdb at mm://localhost:1234")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:metamatrix:jvdb at mm://localhost:1234")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234;version=x")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234,localhost2:12342,localhost3:12343")); //$NON-NLS-1$       
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mms://localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:jvdb at mms://localhost:1234")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234;version=x")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://localhost:1234,localhost2:12342,localhost3:12343")); //$NON-NLS-1$       
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mms://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mms://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://127.0.0.1:1234;logLevel=2")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mms://127.0.0.1:1234")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://127.0.0.1:1234,localhost.mydomain.com:63636;logLevel=2")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://my-host.mydomain.com:53535,127.0.0.1:1234")); //$NON-NLS-1$
+        assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://123.123.123.123:53535,127.0.0.1:1234")); //$NON-NLS-1$
+        
+        assertTrue(!SocketProfile.acceptsURL("jdbc:metamatrix:jvdb at localhost:1234")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb at localhost:1234")); //$NON-NLS-1$
+
+        //DQP type
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb at c:/dqp.properties;version=1")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb@/foo/dqp.properties;version=1")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb at ../foo/dqp.properties;version=1")); //$NON-NLS-1$
+        
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb at mm://localhost:port")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:vdb at localhost:port;version=x")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234,localhost2:12342,localhost3:12343")); //$NON-NLS-1$       
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;stickyConnections=false;socketsPerVM=4")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:vdb at mm://my_host.mydomain.com:53535,127.0.0.1:1234")); //$NON-NLS-1$        
+    }
+
+    /** Invalid format of urls*/
+    @Test public void testAcceptsURL2() throws Exception    {
+        assertTrue(!SocketProfile.acceptsURL("jdbc:matamatrix:test")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("metamatrix:test")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc&matamatrix:test")); //$NON-NLS-1$
+        assertTrue(!SocketProfile.acceptsURL("jdbc;metamatrix:test")); //$NON-NLS-1$
+    }   
+
+    @Test public void testParseURL() throws SQLException{
+        Properties p = new Properties();
+        SocketProfile.parseURL("jdbc:teiid:BQT at mm://slwxp157:1234", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234")); //$NON-NLS-1$
+        assertEquals(3, p.size());        
+    }
+
+    @Test public void testParseURL2() throws SQLException {
+        Properties p = new Properties();       
+        SocketProfile.parseURL("jdbc:teiid:BQT at mms://slwxp157:1234;version=3", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("3")); //$NON-NLS-1$
+        assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mms://slwxp157:1234")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VERSION).equals("3")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals(BaseDataSource.DEFAULT_APP_NAME));
+        assertEquals(5, p.size());
+    }
+    
+    @Test public void testParseURL3() throws SQLException{
+        Properties p = new Properties();
+        SocketProfile.parseURL("jdbc:teiid:BQT at mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302;version=4;autoCommitTxn=ON;partialResultsMode=YES;ApplicationName=Client", p); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("4"));         //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP).equals("ON")); //$NON-NLS-1$
+        assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("YES")); //$NON-NLS-1$
+        assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.VERSION).equals("4")); //$NON-NLS-1$
+        assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals("Client")); //$NON-NLS-1$
+        assertEquals(7, p.size());        
+    }    
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,633 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.teiid.jdbc.BaseDataSource;
+import org.teiid.jdbc.TeiidDataSource;
+
+import junit.framework.TestCase;
+
+import com.metamatrix.core.util.UnitTestUtil;
+
+public class TestTeiidDataSource extends TestCase {
+
+    protected static final boolean VALID = true;
+    protected static final boolean INVALID = false;
+
+    private TeiidDataSource dataSource;
+
+    protected static final String STD_SERVER_NAME           = "unitTestServerName"; //$NON-NLS-1$
+    protected static final String STD_DATABASE_NAME         = "unitTestVdbName"; //$NON-NLS-1$
+    protected static final String STD_DATABASE_VERSION      = "unitTestVdbVersion"; //$NON-NLS-1$
+    protected static final String STD_DATA_SOURCE_NAME      = "unitTestDataSourceName"; //$NON-NLS-1$
+    protected static final int    STD_PORT_NUMBER           = 7001;
+    protected static final String STD_LOG_FILE              = UnitTestUtil.getTestScratchPath() + "/unitTestLogFile"; //$NON-NLS-1$
+    protected static final int    STD_LOG_LEVEL             = 2;
+    protected static final String STD_TXN_WRAP         = TeiidDataSource.TXN_WRAP_AUTO;
+    protected static final String STD_PARTIAL_MODE         = "false"; //$NON-NLS-1$
+    protected static final String STD_CONFIG_FILE          = UnitTestUtil.getTestDataPath() + "/bqt/bqt.properties";  //$NON-NLS-1$
+    protected static final String STD_ALTERNATE_SERVERS     = "unitTestServerName2:7001,unitTestServerName2:7002,unitTestServerName3:7001"; //$NON-NLS-1$
+
+    /**
+     * Constructor for TestTeiidDataSource.
+     * @param name
+     */
+    public TestTeiidDataSource(String name) {
+        super(name);
+    }
+
+    /**
+     * @see TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        dataSource = new TeiidDataSource();
+        dataSource.setServerName(STD_SERVER_NAME);
+        dataSource.setDatabaseVersion(STD_DATABASE_VERSION);
+        dataSource.setDatabaseName(STD_DATABASE_NAME);
+        dataSource.setPortNumber(STD_PORT_NUMBER);
+        dataSource.setDataSourceName(STD_DATA_SOURCE_NAME);
+        dataSource.setTransactionAutoWrap(STD_TXN_WRAP);
+        dataSource.setPartialResultsMode(STD_PARTIAL_MODE);
+        dataSource.setSecure(true);
+        dataSource.setAlternateServers(STD_ALTERNATE_SERVERS);
+    }
+
+    // =========================================================================
+    //                      H E L P E R   M E T H O D S
+    // =========================================================================
+
+    protected String getReasonWhyInvalid( final String propertyName, final String value ) {
+        if ( propertyName.equals("DatabaseName") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidDatabaseName(value);
+        } else if ( propertyName.equals("DatabaseVersion") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidDatabaseVersion(value);
+        } else if ( propertyName.equals("DataSourceName") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidDataSourceName(value);
+        } else if ( propertyName.equals("Description") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidDescription(value);
+        } else if ( propertyName.equals("ServerName") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidServerName(value);
+        } else if ( propertyName.equals("TransactionAutoWrap") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidTransactionAutoWrap(value);
+        } else if ( propertyName.equals("partialResultsMode")) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidPartialResultsMode(value);
+        } else if ( propertyName.equals("socketsPerVM")) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidSocketsPerVM(value);
+        } else if ( propertyName.equals("stickyConnections")) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidStickyConnections(value);
+        } else if ( propertyName.equals("alternateServers")) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidAlternateServers(value);
+        }
+
+        fail("Unknown property name \"" + propertyName + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+        return null;
+    }
+
+    protected String getReasonWhyInvalid( final String propertyName, final int value ) {
+    	if ( propertyName.equals("PortNumber") ) { //$NON-NLS-1$
+            return TeiidDataSource.reasonWhyInvalidPortNumber(value);
+        }
+        fail("Unknown property name \"" + propertyName + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+        return null;
+    }
+
+    public void helpTestReasonWhyInvalid( final String propertyName, final String value,
+                                          final boolean shouldBeValid) {
+        final String reason = getReasonWhyInvalid(propertyName,value);
+        if ( shouldBeValid ) {
+            assertNull("Unexpectedly considered invalid value \"" + value + "\"; reason = " + reason,reason); //$NON-NLS-1$ //$NON-NLS-2$
+        } else {
+            assertNotNull("Unexpectedly found no reason for value \"" + value + "\"",reason); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    public void helpTestReasonWhyInvalid( final String propertyName, final int value,
+                                          final boolean shouldBeValid) {
+        final String reason = getReasonWhyInvalid(propertyName,value);
+        if ( shouldBeValid ) {
+            assertNull("Unexpectedly considered invalid value " + value + "; reason = " + reason,reason); //$NON-NLS-1$ //$NON-NLS-2$
+        } else {
+            assertNotNull("Unexpectedly found no reason for value " + value,reason); //$NON-NLS-1$
+        }
+    }
+
+    public void helpTestBuildingURL( final String vdbName, final String vdbVersion,
+                                     final String serverName, final int portNumber,
+                                     final String alternateServers,
+                                     final String txnAutoWrap, final String partialMode,
+                                     final int fetchSize, final boolean showPlan,
+                                     final boolean secure, final String expectedURL) {
+
+        final TeiidDataSource ds = new TeiidDataSource();
+        ds.setServerName(serverName);
+        ds.setDatabaseVersion(vdbVersion);
+        ds.setDatabaseName(vdbName);
+        ds.setPortNumber(portNumber);
+        ds.setFetchSize(fetchSize);
+        ds.setTransactionAutoWrap(txnAutoWrap);
+        ds.setPartialResultsMode(partialMode);
+        if(showPlan) {
+            ds.setSqlOptions(ExecutionProperties.SQL_OPTION_SHOWPLAN);
+        }
+        ds.setSecure(secure);
+        ds.setAlternateServers(alternateServers);
+
+        final String url = ds.buildURL();
+        assertEquals(expectedURL, url);
+    }
+
+    public Connection helpTestConnection( final String vdbName, final String vdbVersion,
+                                    final String serverName, final int portNumber, final String alternateServers, 
+                                    final String user, final String password,
+                                    final String dataSourceName,
+                                    final String txnAutoWrap, final String partialMode,
+                                    final String configFile )
+                                    throws SQLException {
+
+    	TeiidDataSource ds = new TeiidDataSource();
+
+        ds.setServerName(serverName);
+        ds.setDatabaseVersion(vdbVersion);
+        ds.setDatabaseName(vdbName);
+        ds.setPortNumber(portNumber);
+        ds.setUser(user);
+        ds.setPassword(password);
+        ds.setDataSourceName(dataSourceName);
+        ds.setTransactionAutoWrap(txnAutoWrap);
+        ds.setPartialResultsMode(partialMode);
+        ds.setAlternateServers(alternateServers);
+
+        return ds.getConnection();
+
+    }
+
+    // =========================================================================
+    //                         T E S T     C A S E S
+    // =========================================================================
+
+    // ----------------------------------------------------------------
+    //                       Test Getters
+    // ----------------------------------------------------------------
+
+    public void testGetServerName() {
+        final String result = dataSource.getServerName();
+        assertEquals(result,STD_SERVER_NAME);
+    }
+
+    public void testGetDatabaseVersion() {
+        final String result = dataSource.getDatabaseVersion();
+        assertEquals(result,STD_DATABASE_VERSION);
+    }
+
+    public void testGetDatabaseName() {
+        final String result = dataSource.getDatabaseName();
+        assertEquals(result,STD_DATABASE_NAME);
+    }
+
+    public void testGetDefaultApplicationName() {
+        final String result = dataSource.getApplicationName();
+        assertEquals(result,BaseDataSource.DEFAULT_APP_NAME);
+    }
+    
+    public void testGetApplicationName() {
+    	dataSource.setApplicationName("ClientApp"); //$NON-NLS-1$
+        final String result = dataSource.getApplicationName();
+        assertEquals(result,"ClientApp"); //$NON-NLS-1$
+    }
+    
+    public void testGetPortNumber() {
+        final int result = dataSource.getPortNumber();
+        assertEquals(result,STD_PORT_NUMBER);
+    }
+
+    public void testGetDataSourceName() {
+        final String result = dataSource.getDataSourceName();
+        assertEquals(result,STD_DATA_SOURCE_NAME);
+    }
+
+    public void testGetLoginTimeout() {
+        try {
+            final int actual = 1000;
+            dataSource.setLoginTimeout(actual);
+            final int result = dataSource.getLoginTimeout();
+            assertEquals(result,actual);
+        } catch ( SQLException e ) {
+            fail("Error obtaining login timeout"); //$NON-NLS-1$
+        }
+    }
+
+    public void testGetLogWriter() {
+        try {
+            final PrintWriter actual = new PrintWriter( new ByteArrayOutputStream() );
+            dataSource.setLogWriter(actual);
+            final PrintWriter result = dataSource.getLogWriter();
+            assertEquals(result,actual);
+        } catch ( SQLException e ) {
+            fail("Error obtaining login timeout"); //$NON-NLS-1$
+        }
+    }
+
+    public void testGetTransactionAutoWrap() {
+        final String result = dataSource.getTransactionAutoWrap();
+        assertEquals(result,STD_TXN_WRAP);
+    }
+    
+    public void testGetShowPlan() {
+        assertTrue(dataSource.getSqlOptions() == null);
+        dataSource.setSqlOptions(ExecutionProperties.SQL_OPTION_SHOWPLAN);
+        assertTrue(dataSource.getSqlOptions() == ExecutionProperties.SQL_OPTION_SHOWPLAN);
+        dataSource.setSqlOptions(null);
+        assertTrue(dataSource.getSqlOptions() == null);
+    }
+
+    public void testGetSecure() {
+        assertTrue(dataSource.isSecure());
+        dataSource.setSecure(false);
+        assertFalse(dataSource.isSecure());        
+    }
+
+    public void testGetAlternateServers() {
+    	String result = dataSource.getAlternateServers();
+    	assertEquals(result,STD_ALTERNATE_SERVERS);
+    	dataSource.setAlternateServers(null);
+    	result = dataSource.getAlternateServers();
+    	assertNull(result);
+    	dataSource.setAlternateServers(STD_ALTERNATE_SERVERS);
+    	result = dataSource.getAlternateServers();
+    	assertEquals(result,STD_ALTERNATE_SERVERS);
+    }
+
+    // ----------------------------------------------------------------
+    //                       Test invalid reasons
+    // ----------------------------------------------------------------
+
+    public void testReasonWhyInvalidDatabaseName1() {
+        helpTestReasonWhyInvalid("DatabaseName", "Valid VDB Name", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseName2() {
+        helpTestReasonWhyInvalid("DatabaseName", "", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseName3() {
+        helpTestReasonWhyInvalid("DatabaseName", null, INVALID); //$NON-NLS-1$
+    }
+
+
+    public void testReasonWhyInvalidDatabaseVersion1() {
+        helpTestReasonWhyInvalid("DatabaseVersion", "Valid VDB Version", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseVersion2() {
+        helpTestReasonWhyInvalid("DatabaseVersion", "1", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseVersion3() {
+        helpTestReasonWhyInvalid("DatabaseVersion", "1.2.3", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseVersion4() {
+        helpTestReasonWhyInvalid("DatabaseVersion", "1 2 3", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseVersion5() {
+        helpTestReasonWhyInvalid("DatabaseVersion", "", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDatabaseVersion6() {
+        helpTestReasonWhyInvalid("DatabaseVersion", null, VALID); //$NON-NLS-1$
+    }
+
+
+    public void testReasonWhyInvalidDataSourceName1() {
+        helpTestReasonWhyInvalid("DataSourceName", "Valid Data Source Name", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDataSourceName2() {
+        helpTestReasonWhyInvalid("DataSourceName", "", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDataSourceName3() {
+        helpTestReasonWhyInvalid("DataSourceName", "", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+
+    public void testReasonWhyInvalidDescription1() {
+        helpTestReasonWhyInvalid("Description", "Valid App Name", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDescription2() {
+        helpTestReasonWhyInvalid("Description", "", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidDescription3() {
+        helpTestReasonWhyInvalid("Description", null, VALID); //$NON-NLS-1$
+    }
+
+    public void testReasonWhyInvalidPortNumber1() {
+        helpTestReasonWhyInvalid("PortNumber", 1, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidPortNumber2() {
+        helpTestReasonWhyInvalid("PortNumber", 9999999, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidPortNumber3() {
+        helpTestReasonWhyInvalid("PortNumber", 0, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidPortNumber4() {
+        helpTestReasonWhyInvalid("PortNumber", -1, INVALID); //$NON-NLS-1$
+    }
+
+
+    public void testReasonWhyInvalidServerName1() {
+        helpTestReasonWhyInvalid("ServerName", "Valid Server Name", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidServerName2() {
+        helpTestReasonWhyInvalid("ServerName", "Valid Server Name", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidServerName3() {
+        helpTestReasonWhyInvalid("ServerName", "", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidServerName4() {
+        helpTestReasonWhyInvalid("ServerName", null, INVALID); //$NON-NLS-1$
+    }
+
+
+    public void testReasonWhyInvalidTransactionAutoWrap1() {
+        helpTestReasonWhyInvalid("TransactionAutoWrap", TeiidDataSource.TXN_WRAP_OFF, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidTransactionAutoWrap2() {
+        helpTestReasonWhyInvalid("TransactionAutoWrap", TeiidDataSource.TXN_WRAP_ON, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidTransactionAutoWrap3() {
+        helpTestReasonWhyInvalid("TransactionAutoWrap", TeiidDataSource.TXN_WRAP_AUTO, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidTransactionAutoWrap5() {
+        helpTestReasonWhyInvalid("TransactionAutoWrap", "off", INVALID);    // lowercase value //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidTransactionAutoWrap6() {
+        helpTestReasonWhyInvalid("TransactionAutoWrap", "Invalid AutoWrap", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testreasonWhyInvalidPartialResultsMode1() {
+        helpTestReasonWhyInvalid("partialResultsMode", "Invalid partial mode", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testreasonWhyInvalidPartialResultsMode2() {
+        helpTestReasonWhyInvalid("partialResultsMode", "true", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testReasonWhyInvalidSocketsPerVM1() {
+        helpTestReasonWhyInvalid("socketsPerVM", null, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidSocketsPerVM2() {
+        helpTestReasonWhyInvalid("socketsPerVM", "4", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidSocketsPerVM3() {
+        helpTestReasonWhyInvalid("socketsPerVM", "-3", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidSocketsPerVM4() {
+        helpTestReasonWhyInvalid("socketsPerVM", "5.6", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testReasonWhyInvalidStickyConnections1() {
+        helpTestReasonWhyInvalid("stickyConnections", null, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidStickyConnections2() {
+        helpTestReasonWhyInvalid("stickyConnections", "false", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidStickyConnections3() {
+        helpTestReasonWhyInvalid("stickyConnections", "YES", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testReasonWhyInvalidAlternateServers1() {
+    	helpTestReasonWhyInvalid("alternateServers", null, VALID); //$NON-NLS-1$
+    }
+    public void testReasonWhyInvalidAlternateServers2() {
+    	helpTestReasonWhyInvalid("alternateServers", "", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers3() {
+    	helpTestReasonWhyInvalid("alternateServers", "server", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers4() {
+    	helpTestReasonWhyInvalid("alternateServers", "server:100", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers5() {
+    	helpTestReasonWhyInvalid("alternateServers", "server:port", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers6() {
+    	helpTestReasonWhyInvalid("alternateServers", "server:100:1", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers7() {
+    	helpTestReasonWhyInvalid("alternateServers", "server:100:abc", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers8() {
+    	helpTestReasonWhyInvalid("alternateServers", "server:abc:100", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers9() {
+    	helpTestReasonWhyInvalid("alternateServers", ":100", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers10() {
+    	helpTestReasonWhyInvalid("alternateServers", ":abc", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers11() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1:100,server2", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers12() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1:100,server2:101", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers13() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1:100,", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers14() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1:100,server2:abc", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers15() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1:100,server2:101:abc", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers16() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1,server2:100", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers17() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1,server2", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers18() {
+    	helpTestReasonWhyInvalid("alternateServers", ",server2:100", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    public void testReasonWhyInvalidAlternateServers19() {
+    	helpTestReasonWhyInvalid("alternateServers", "server1,server2,server3,server4:500", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+
+    
+    
+    // ----------------------------------------------------------------
+    //                       Test building URLs
+    // ----------------------------------------------------------------
+
+    public void testBuildingURL1() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = "1.2.3"; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String transactionAutoWrap = null;
+        final String partialMode = "true"; //$NON-NLS-1$
+        final boolean secure = false;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap, partialMode, 500, false, secure,
+                            "jdbc:teiid:vdbName at mm://hostname:7001;fetchSize=500;ApplicationName=JDBC;VirtualDatabaseVersion=1.2.3;partialResultsMode=true;VirtualDatabaseName=vdbName"); //$NON-NLS-1$
+    }
+
+    public void testBuildingURL2() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+        final String partialMode = "false"; //$NON-NLS-1$
+        final boolean secure = false;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap, partialMode, -1, false, secure, 
+                            "jdbc:teiid:vdbName at mm://hostname:7001;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName"); //$NON-NLS-1$ 
+    }
+    
+    public void testBuildURL3() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+        final String partialMode = "false"; //$NON-NLS-1$
+        final boolean secure = false;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap, partialMode, -1, true, secure,
+                            "jdbc:teiid:vdbName at mm://hostname:7001;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN"); //$NON-NLS-1$ 
+    }
+
+    // Test secure protocol
+    public void testBuildURL4() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+        final String partialMode = "false"; //$NON-NLS-1$
+        final boolean secure = true;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap, partialMode, -1, true, secure,
+                            "jdbc:teiid:vdbName at mms://hostname:7001;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN"); //$NON-NLS-1$ 
+    }
+
+    /*
+     * Test alternate servers list
+     * 
+     * Server list uses server:port pairs
+     */ 
+    public void testBuildURL5() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String alternateServers = "hostName:7002,hostName2:7001,hostName2:7002"; //$NON-NLS-1$
+        final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+        final String partialMode = "false"; //$NON-NLS-1$
+        final boolean secure = false;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,alternateServers,transactionAutoWrap, partialMode, -1, true, secure,
+                            "jdbc:teiid:vdbName at mm://hostName:7001,hostName:7002,hostName2:7001,hostName2:7002;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN"); //$NON-NLS-1$ 
+    }
+
+    /*
+     * Test alternate servers list
+     * 
+     * Server list uses server:port pairs and we set secure to true
+     */ 
+    public void testBuildURL6() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String alternateServers = "hostName:7002,hostName2:7001,hostName2:7002"; //$NON-NLS-1$
+        final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+        final String partialMode = "false"; //$NON-NLS-1$
+        final boolean secure = true;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,alternateServers,transactionAutoWrap, partialMode, -1, true, secure,
+                            "jdbc:teiid:vdbName at mms://hostName:7001,hostName:7002,hostName2:7001,hostName2:7002;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN"); //$NON-NLS-1$ 
+    }
+
+    /*
+     * Test alternate servers list
+     * 
+     * Server list uses server:port pairs and server with no port
+     * In this case, the server with no port should default to ds.portNumber.
+     */ 
+    public void testBuildURL7() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 7001;
+        final String alternateServers = "hostName:7002,hostName2,hostName2:7002"; //$NON-NLS-1$
+        final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+        final String partialMode = "false"; //$NON-NLS-1$
+        final boolean secure = false;
+        helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,alternateServers,transactionAutoWrap, partialMode, -1, true, secure,
+                            "jdbc:teiid:vdbName at mm://hostName:7001,hostName:7002,hostName2:7001,hostName2:7002;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN"); //$NON-NLS-1$ 
+    }
+    
+    public void testBuildURL_AdditionalProperties() {
+    	final TeiidDataSource ds = new TeiidDataSource();
+    	ds.setAdditionalProperties("foo=bar;a=b"); //$NON-NLS-1$
+    	ds.setServerName("hostName"); //$NON-NLS-1$
+    	ds.setDatabaseName("vdbName"); //$NON-NLS-1$
+    	ds.setPortNumber(1);
+    	assertEquals("jdbc:teiid:vdbName at mm://hostname:1;fetchSize=2048;ApplicationName=JDBC;a=b;VirtualDatabaseName=vdbName;foo=bar", ds.buildURL()); //$NON-NLS-1$
+    }
+
+    public void testInvalidDataSource() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = -1;              // this is what is invalid
+        final String dataSourceName = null;
+        final String transactionAutoWrap = null;
+        final String configFile = UnitTestUtil.getTestDataPath() + "/config.txt"; //$NON-NLS-1$
+        try {
+            helpTestConnection(vdbName,vdbVersion,serverName,portNumber, null, null, null, dataSourceName,transactionAutoWrap,
+                "false", configFile);       // TRUE TO OVERRIDE USERNAME & PASSWORD //$NON-NLS-1$
+            fail("Unexpectedly able to connect"); //$NON-NLS-1$
+        } catch ( SQLException e) {
+            // this is expected!
+        }
+    }
+    
+    /*
+     * Test invalid alternateServer list
+     * 
+     * Server list uses a non numeric value for port.
+     */ 
+    public void testInvalidDataSource2() {
+        final String serverName = "hostName"; //$NON-NLS-1$
+        final String vdbName = "vdbName"; //$NON-NLS-1$
+        final String vdbVersion = ""; //$NON-NLS-1$
+        final int portNumber = 31000;
+        final String alternateServers = "hostName:-1"; // this is what is invalid //$NON-NLS-1$
+        final String dataSourceName = null;
+        final String transactionAutoWrap = null;
+        final String configFile = UnitTestUtil.getTestDataPath() + "/config.txt"; //$NON-NLS-1$
+        try {
+            helpTestConnection(vdbName, vdbVersion, serverName, portNumber, 
+            		alternateServers, null, null, dataSourceName, transactionAutoWrap, "false", configFile);     //$NON-NLS-1$  // TRUE TO OVERRIDE USERNAME & PASSWORD
+            fail("Unexpectedly able to connect"); //$NON-NLS-1$
+        } catch ( SQLException e) {
+            // this is expected!
+        }
+    }
+}
\ No newline at end of file


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestTeiidDriver.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.sql.DriverPropertyInfo;
+
+import org.junit.Test;
+
+public class TestTeiidDriver {
+    TeiidDriver drv = new TeiidDriver();
+
+    
+    @Test public void testGetPropertyInfo1() throws Exception {        
+        DriverPropertyInfo info[] = drv.getPropertyInfo("jdbc:teiid:vdb at mm://localhost:12345", null); //$NON-NLS-1$
+        assertEquals(17, info.length);
+    }
+    
+    @Test public void testAccepts() throws Exception {
+    	assertTrue(drv.acceptsURL("jdbc:teiid:vdb at mm://localhost:12345")); //$NON-NLS-1$
+    	assertTrue(drv.acceptsURL("jdbc:teiid:vdb at mm://localhost:12345;user=foo;password=bar")); //$NON-NLS-1$
+    	assertTrue(drv.acceptsURL("jdbc:teiid:vdb")); //$NON-NLS-1$
+    	assertFalse(drv.acceptsURL("jdbc:teiid:vdb@/foo/blah/deploy.properties")); //$NON-NLS-1$
+    	
+    	assertTrue(drv.acceptsURL("jdbc:teiid:vdb at mm://localhost:12345")); //$NON-NLS-1$
+    	assertTrue(drv.acceptsURL("jdbc:teiid:vdb at mm://localhost:12345;user=foo;password=bar")); //$NON-NLS-1$
+    	assertTrue(drv.acceptsURL("jdbc:teiid:vdb")); //$NON-NLS-1$
+    	assertFalse(drv.acceptsURL("jdbc:teiid:vdb@/foo/blah/deploy.properties")); //$NON-NLS-1$
+    	
+    }
+    
+}


Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestWrapperImpl.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java	                        (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -0,0 +1,91 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.Wrapper;
+
+import org.teiid.jdbc.WrapperImpl;
+//## JDBC4.0-end ##
+
+import junit.framework.TestCase;
+
+public class TestWrapperImpl extends TestCase {
+	//## JDBC4.0-begin ##
+	interface Foo extends Wrapper {
+		void callMe();
+	}
+	
+	static class FooImpl extends WrapperImpl implements Foo {
+		
+		boolean wasCalled;
+		
+		public void callMe() {
+			wasCalled = true;
+		}
+		
+	}
+	//## JDBC4.0-end ##
+	public void testProxy() throws SQLException {
+		//## JDBC4.0-begin ##
+		final FooImpl fooImpl = new FooImpl(); 
+		
+		Foo proxy = (Foo)Proxy.newProxyInstance(TestWrapperImpl.class.getClassLoader(), new Class[] {Foo.class}, new InvocationHandler() {
+
+			public Object invoke(Object arg0, Method arg1, Object[] arg2)
+					throws Throwable {
+				if (arg1.getName().equals("callMe")) {
+					return null;
+				}
+				try {
+					return arg1.invoke(fooImpl, arg2);
+				} catch (InvocationTargetException e) {
+					throw e.getTargetException();
+				}
+			}
+			
+		});
+		
+		proxy.callMe();
+		
+		assertFalse(fooImpl.wasCalled);
+		
+		proxy.unwrap(Foo.class).callMe();
+		
+		assertTrue(fooImpl.wasCalled);
+		
+		try {
+			proxy.unwrap(String.class);
+			fail("expected exception");
+		} catch (SQLException e) {
+			assertEquals("Wrapped object is not an instance of class java.lang.String", e.getMessage());
+		}
+		//## JDBC4.0-end ##
+	}
+
+}

Copied: trunk/client/src/test/java/org/teiid/jdbc/plan (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/plan)

Modified: trunk/client/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java
===================================================================
--- trunk/client-jdbc/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -27,6 +27,10 @@
 import java.util.HashMap;
 import java.util.List;
 
+import org.teiid.client.plan.DefaultDisplayHelper;
+import org.teiid.client.plan.PlanNode;
+import org.teiid.client.plan.TextOutputVisitor;
+
 import junit.framework.TestCase;
 
 

Modified: trunk/client/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java
===================================================================
--- trunk/client-jdbc/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java	2010-03-22 14:47:51 UTC (rev 1983)
+++ trunk/client/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -22,6 +22,9 @@
 
 package org.teiid.jdbc.plan;
 
+import org.teiid.client.plan.DefaultDisplayHelper;
+import org.teiid.client.plan.XMLOutputVisitor;
+
 import junit.framework.TestCase;
 
 

Copied: trunk/client/src/test/java/org/teiid/jdbc/util (from rev 1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/util)

Modified: trunk/console/pom.xml
===================================================================
--- trunk/console/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/console/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -208,16 +208,6 @@
 
 		<dependency>
 			<groupId>org.jboss.teiid</groupId>
-			<artifactId>teiid-client-jdbc</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.jboss.teiid</groupId>
-			<artifactId>teiid-client-jdbc</artifactId>
-			<type>test-jar</type>
-		</dependency>
-
-		<dependency>
-			<groupId>org.jboss.teiid</groupId>
 			<artifactId>teiid-common-core</artifactId>
 		</dependency>
 		<dependency>

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java	2010-03-22 21:01:44 UTC (rev 1986)
@@ -398,17 +398,14 @@
 	private void rollbackDirect(TransactionContext tc)
 			throws XATransactionException {
 		try {
-			this.transactionManager.resume(tc.getTransaction());
     		this.transactionManager.rollback();
 		} catch (SecurityException e) {
 			throw new XATransactionException(e);
 		} catch (SystemException e) {
 			throw new XATransactionException(e);
-		} catch (InvalidTransactionException e) {
-			throw new XATransactionException(e);
-		} finally {
-            transactions.removeTransactionContext(tc);
-        }
+        } finally {
+			transactions.removeTransactionContext(tc);
+		}
 	}
 	
 	public void suspend(TransactionContext context) throws XATransactionException {

Modified: trunk/jboss-integration/pom.xml
===================================================================
--- trunk/jboss-integration/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/jboss-integration/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -73,13 +73,12 @@
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>    
-    
+
     <dependency>
       <groupId>org.jboss.teiid</groupId>
-      <artifactId>teiid-client-jdbc</artifactId>
-      <scope>test</scope>
+      <artifactId>teiid-client</artifactId>
     </dependency>
-        
+            
     <dependency>
         <groupId>org.jboss.naming</groupId>
         <artifactId>jnp-client</artifactId>

Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -275,18 +275,6 @@
 			</dependency>
 			<dependency>
 				<groupId>org.jboss.teiid</groupId>
-				<artifactId>teiid-client-jdbc</artifactId>
-				<version>${project.version}</version>
-			</dependency>
-			<dependency>
-				<groupId>org.jboss.teiid</groupId>
-				<artifactId>teiid-client-jdbc</artifactId>
-				<type>test-jar</type>
-				<version>${project.version}</version>
-				<scope>test</scope>
-			</dependency>
-			<dependency>
-				<groupId>org.jboss.teiid</groupId>
 				<artifactId>teiid-engine</artifactId>
 				<version>${project.version}</version>
 			</dependency>
@@ -482,7 +470,6 @@
 		<module>common-core</module>
 		<module>connector-api</module>
 		<module>client</module>
-		<module>client-jdbc</module>
 		<module>engine</module>
 		<module>connectors</module>
 		<module>console</module>

Modified: trunk/runtime/pom.xml
===================================================================
--- trunk/runtime/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/runtime/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -45,11 +45,6 @@
       <artifactId>teiid-metadata</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.jboss.teiid</groupId>
-      <artifactId>teiid-client-jdbc</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
     	<groupId>org.jboss.teiid</groupId>
     	<artifactId>teiid-cache-jbosscache</artifactId>
     </dependency>

Modified: trunk/test-integration/db/pom.xml
===================================================================
--- trunk/test-integration/db/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/test-integration/db/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -38,7 +38,7 @@
 			
 		<dependency>
 			<groupId>org.jboss.teiid</groupId>
-			<artifactId>teiid-client-jdbc</artifactId>
+			<artifactId>teiid-client</artifactId>
 			<type>test-jar</type>
 			<scope>compile</scope>
 		</dependency>

Modified: trunk/test-integration/pom.xml
===================================================================
--- trunk/test-integration/pom.xml	2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/test-integration/pom.xml	2010-03-22 21:01:44 UTC (rev 1986)
@@ -52,11 +52,11 @@
 		</dependency>
 		<dependency>
 			<groupId>org.jboss.teiid</groupId>
-			<artifactId>teiid-client-jdbc</artifactId>
+			<artifactId>teiid-client</artifactId>
 		</dependency>
 		<dependency>
 			<groupId>org.jboss.teiid</groupId>
-			<artifactId>teiid-client-jdbc</artifactId>
+			<artifactId>teiid-client</artifactId>
 			<type>test-jar</type>
 		</dependency>
 		<dependency>



More information about the teiid-commits mailing list