Author: shawkins
Date: 2011-07-22 12:26:08 -0400 (Fri, 22 Jul 2011)
New Revision: 3327
Added:
trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected
Modified:
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java
trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml
trunk/engine/pom.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java
trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java
trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
trunk/pom.xml
trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected
Log:
forward merge of 7.4.1
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -284,8 +284,7 @@
if(elementID != null) {
elemShortName = getName(elementID);
} else {
- String elementName = obj.getName();
- elemShortName = getShortName(elementName);
+ elemShortName = obj.getName();
}
// Check whether a subclass wants to replace the element name to use in special
circumstances
Modified:
trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
===================================================================
---
trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-22
16:26:08 UTC (rev 3327)
@@ -85,7 +85,7 @@
<!-- Hibernate 2LC can replicate custom types, so we use
marshalling -->
<property
name="useRegionBasedMarshalling">true</property>
<!-- Must match the value of
"useRegionBasedMarshalling" -->
- <property
name="inactiveOnStartup">true</property>
+ <property
name="inactiveOnStartup">false</property>
<!-- Disable asynchronous RPC marshalling/sending -->
<property
name="serializationExecutorPoolSize">0</property>
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-07-22 15:32:56 UTC (rev
3326)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-07-22 16:26:08 UTC (rev
3327)
@@ -34,7 +34,9 @@
<LI><B>Streaming XQuery</B> - in situations where document projection
applies if the XMLQUERY/XMLTABLE path expressions meet certain conditions, then the
incoming document will not only be projected, but the independent subtrees will be
processed without loading the entire document. This allows for nearly arbitrarily large
XML documents to be processed. See the Reference for more.
<LI><B>Logging Procedures</B> - added SYSADMIN.isLoggable and
SYSADMIN.logMsg to aid in debugging procedure logic.
<LI><B>ANSI OFFSET/FETCH FIRST</B> - instead of the limit clause, a
standard OFFSET and/or FETCH FIRST/NEXT clause can be used to limit results.
+ <LI><B>ODBC Cursors</B> - Capability to use
"UseDeclareFetch" with ODBC is added. This enables user to read the results in
batches, especially useful when dealing with large row count of results.
</UL>
+
<h2><a name="Compatibility">Compatibility
Issues</a></h2>
<ul>
<li>TRANSLATE/HAS CRITERIA has been deprecated. An alternative approach to
update procedures will be introduced in a subsequent version.
@@ -45,6 +47,8 @@
<h4>from 7.4</h4>
<ul>
<li>OFFSET was added as a keyword.
+ <li>ColumnReference.getName will always return just the element name. Previously
it inconsistently returned the qualified and unqualified form depending upon where the
ColumnReference appeared.
+ <li>As per JDBC4, ResultSetMetadata.getColumnName will return the unaliased
column name if available rather than return the alias. Set
useJDBC4ColumnNameAndLabelSemantics to false to use the alias name as the column name.
</ul>
<h4>from 7.3</h4>
Modified:
trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
===================================================================
---
trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -59,6 +59,7 @@
if (!this.cacheStore.getCacheStatus().allowInvocations()) {
this.cacheStore.start();
+ this.cacheStore.getRegion(this.cacheStore.getRoot().getFqn(), true).activate();
}
Node cacheRoot =
this.cacheStore.getRoot().addChild(Fqn.fromString("Teiid")); //$NON-NLS-1$
@@ -67,6 +68,7 @@
Region cacheRegion = this.cacheStore.getRegion(node.getFqn(), true);
cacheRegion.setEvictionRegionConfig(buildEvictionConfig(node.getFqn(), config));
+ cacheRegion.activate();
JBossCache jc = null;
if (config != null && config.getPolicy().equals(Policy.EXPIRATION)) {
Modified: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -1433,18 +1433,21 @@
// 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);
- }
- }
+ StringBuffer typesString = new StringBuffer("("); // criteria string
for different table types //$NON-NLS-1$
+ if (types.length == 0) {
+ typesString.append("1 = 0"); //$NON-NLS-1$
+ } else {
+ // 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$
}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
___________________________________________________________________
Added: svn:mergeinfo
+
/branches/7.4.x/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java:3281-3325
Modified: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2011-07-22 15:32:56 UTC (rev
3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2011-07-22 16:26:08 UTC (rev
3327)
@@ -58,7 +58,8 @@
ExecutionProperties.PROP_XML_FORMAT,
ExecutionProperties.PROP_XML_VALIDATION,
EmbeddedProfile.USE_CALLING_THREAD,
- ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS)));
+ ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS,
+ ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS)));
public static final Set<String> KNOWN_PROPERTIES = getKnownProperties();
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java:3149-3217
+ /branches/7.4.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java:3149-3217,3281-3325
Modified: trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -39,7 +39,9 @@
public ResultSetMetaDataImpl(MetadataProvider provider, String
supportBackwardsCompatibility) {
this.provider = provider;
- this.useJDBC4ColumnNameAndLabelSemantics = (supportBackwardsCompatibility != null
&& supportBackwardsCompatibility.equalsIgnoreCase("false") ? false :
true);
+ if (supportBackwardsCompatibility != null) {
+ this.useJDBC4ColumnNameAndLabelSemantics =
Boolean.parseBoolean(supportBackwardsCompatibility);
+ }
}
/**
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
___________________________________________________________________
Added: svn:mergeinfo
+
/branches/7.4.x/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java:3281-3325
Modified: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-07-22 15:32:56 UTC
(rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-07-22 16:26:08 UTC
(rev 3327)
@@ -40,8 +40,6 @@
import java.util.Properties;
import java.util.TimeZone;
import java.util.concurrent.ExecutionException;
-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;
@@ -538,11 +536,7 @@
});
if (synch) {
try {
- if (queryTimeoutMS > 0) {
- pendingResult.get(queryTimeoutMS, TimeUnit.MILLISECONDS);
- } else {
- pendingResult.get();
- }
+ pendingResult.get();
result.get(); //throw an exception if needed
return result;
} catch (ExecutionException e) {
@@ -552,8 +546,6 @@
throw TeiidSQLException.create(e);
} catch (InterruptedException e) {
timeoutOccurred();
- } catch (TimeoutException e) {
- timeoutOccurred();
}
throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Timeout_before_complete"));
//$NON-NLS-1$
}
@@ -578,7 +570,7 @@
reqMsg.setExecutionId(this.currentRequestID);
ResultsFuture.CompletionListener<ResultsMessage> compeletionListener =
null;
- if (queryTimeoutMS > 0 && !synch) {
+ if (queryTimeoutMS > 0) {
final CancelTask c = new QueryTimeoutCancelTask(queryTimeoutMS, this);
cancellationTimer.add(c);
compeletionListener = new ResultsFuture.CompletionListener<ResultsMessage>() {
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
___________________________________________________________________
Modified: svn:mergeinfo
-
/branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java:3149-3217,3220-3275
+
/branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java:3149-3217,3220-3275,3281-3325
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java 2011-07-22 15:32:56 UTC
(rev 3326)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java 2011-07-22 16:26:08 UTC
(rev 3327)
@@ -22,7 +22,8 @@
package org.teiid.jdbc;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.stub;
import java.sql.SQLException;
import java.util.Properties;
@@ -38,8 +39,6 @@
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;
@@ -48,13 +47,28 @@
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@mm://localhost:7001;version=1;user=metamatrixadmin;password=mm";
//$NON-NLS-1$
+ static String serverUrl =
"jdbc:teiid:QT_Ora9DS@mm://localhost:7001;version=1;user=metamatrixadmin;password=mm";
//$NON-NLS-1$
public TestConnection(String name) {
super(name);
}
+ static class InnerDriver extends TeiidDriver {
+ String iurl = null;
+ public InnerDriver(String url) {
+ iurl = url;
+ }
+
+ public void parseUrl(Properties props) throws SQLException {
+ super.parseURL(iurl, props);
+ }
+ }
+
public static ConnectionImpl getMMConnection() {
+ return getMMConnection(serverUrl);
+ }
+
+ public static ConnectionImpl getMMConnection(String url) {
ServerConnection mock = mock(ServerConnection.class);
DQP dqp = mock(DQP.class);
try {
@@ -79,13 +93,20 @@
} catch (XATransactionException e) {
throw new RuntimeException(e);
}
+
+ Properties props = new Properties();
+
+ try {
+ new InnerDriver(url).parseUrl(props);
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
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);
+
+ stub(mock.getLogonResult()).toReturn(new LogonResult(new SessionToken(1,
"admin"), STD_DATABASE_NAME,STD_DATABASE_VERSION , "fake"));
//$NON-NLS-1$
+ return new ConnectionImpl(mock, props, url);
}
public void testGetMetaData() throws Exception {
@@ -103,7 +124,7 @@
/** 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$
+ assertEquals("Actual userName is not equal to the expected one. ",
"admin", getMMConnection().getUserName()); //$NON-NLS-1$ //$NON-NLS-2$
}
/** test isReadOnly default value on Connection */
@@ -129,4 +150,27 @@
// error expected
}
}
+
+ /**
+ * Test the default of the JDBC4 spec semantics is true
+ */
+ public void testDefaultSpec() throws Exception {
+ assertEquals("true",
+
(getMMConnection().getExecutionProperties().getProperty(ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS)
== null ? "true" : "false"));
+ }
+
+ /**
+ * Test turning off the JDBC 4 semantics
+ */
+ public void testTurnOnSpec() throws Exception {
+ assertEquals("true", getMMConnection(serverUrl +
";useJDBC4ColumnNameAndLabelSemantics=true").getExecutionProperties().getProperty(ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS));
+ }
+
+ /**
+ * Test turning off the JDBC 4 semantics
+ */
+ public void testTurnOffSpec() throws Exception {
+ assertEquals("false", getMMConnection(serverUrl +
";useJDBC4ColumnNameAndLabelSemantics=false").getExecutionProperties().getProperty(ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS));
+ }
+
}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/client/src/test/java/org/teiid/jdbc/TestConnection.java:3281-3325
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2011-07-22 15:32:56 UTC
(rev 3326)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2011-07-22 16:26:08 UTC
(rev 3327)
@@ -138,7 +138,7 @@
@Test public void testGetPropertyInfo1() throws Exception {
DriverPropertyInfo info[] =
drv.getPropertyInfo("jdbc:teiid:vdb@mm://localhost:12345;applicationName=x",
null); //$NON-NLS-1$
- assertEquals(20, info.length);
+ assertEquals(21, 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/TestTeiidDriver.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java:3149-3217
+
/branches/7.4.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java:3149-3217,3281-3325
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java
===================================================================
---
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -24,6 +24,8 @@
*/
package org.teiid.translator.jdbc.sqlserver;
+import java.sql.Date;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -203,8 +205,16 @@
}
@Override
+ public String translateLiteralDate(Date dateValue) {
+ if (getDatabaseVersion().compareTo(V_2008) >= 0) {
+ return super.translateLiteralDate(dateValue);
+ }
+ return super.translateLiteralTimestamp(new Timestamp(dateValue.getTime()));
+ }
+
+ @Override
public boolean hasTimeType() {
- return getDatabaseVersion().compareTo(V_2005) >= 0;
+ return getDatabaseVersion().compareTo(V_2008) >= 0;
}
@Override
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
===================================================================
---
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -29,13 +29,21 @@
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.teiid.language.ColumnReference;
+import org.teiid.language.Command;
+import org.teiid.language.DerivedColumn;
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.LanguageFactory;
import org.teiid.language.Literal;
+import org.teiid.language.QueryExpression;
+import org.teiid.language.Select;
+import org.teiid.language.SortSpecification;
+import org.teiid.translator.ExecutionContext;
import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
@@ -107,21 +115,12 @@
convert.addNumericBooleanConversions();
registerFunctionModifier(SourceSystemFunctions.CONVERT, convert);
- registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new
SubstrModifier(this.convert));
+ registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new
AliasModifier("substr")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.RAND, new
AliasModifier("random")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.LOG, new AliasModifier("LN"));
//$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LCASE, new
StringOnlyModifier("LOWER", this.convert)); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.UCASE, new
StringOnlyModifier("UPPER", this.convert)); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LENGTH, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
- target.add("character_length("); //$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- });
+ registerFunctionModifier(SourceSystemFunctions.LCASE, new
AliasModifier("LOWER")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.UCASE, new
AliasModifier("UPPER")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LENGTH, new
AliasModifier("character_length")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CURDATE, new
AliasModifier("CURRENT_DATE")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CURTIME, new
AliasModifier("CURRENT_TIME")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.YEAR, new
ExtractModifier("YEAR")); //$NON-NLS-1$
@@ -143,9 +142,9 @@
registerFunctionModifier(SourceSystemFunctions.LTRIM, new FunctionModifier() {
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
target.add("TRIM(LEADING FROM ");//$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
+ target.add(function.getParameters().get(0));
target.add(")"); //$NON-NLS-1$
return target;
}
@@ -153,9 +152,9 @@
registerFunctionModifier(SourceSystemFunctions.RTRIM, new FunctionModifier() {
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
target.add("TRIM(TRAILING FROM ");//$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
+ target.add(function.getParameters().get(0));
target.add(")"); //$NON-NLS-1$
return target;
}
@@ -216,7 +215,7 @@
@Override
- public List getSupportedFunctions() {
+ public List<String> getSupportedFunctions() {
List<String> supportedFunctions = new ArrayList<String>();
supportedFunctions.addAll(super.getSupportedFunctions());
@@ -317,8 +316,37 @@
}
@Override
- public boolean supportsSetQueryOrderBy() {
- return false;
+ public List<?> translateCommand(Command command, ExecutionContext context) {
+ if (command instanceof QueryExpression) {
+ QueryExpression qe = (QueryExpression)command;
+ //teradata prefers positional ordering
+ if (qe.getOrderBy() != null) {
+ Select select = qe.getProjectedQuery();
+ List<DerivedColumn> derivedColumns = select.getDerivedColumns();
+ Map<String, Integer> positions = new HashMap<String, Integer>();
+ int i = 1;
+ for (DerivedColumn derivedColumn : derivedColumns) {
+ String name = derivedColumn.getAlias();
+ if (name == null && derivedColumn.getExpression() instanceof
ColumnReference) {
+ ColumnReference cr = (ColumnReference)derivedColumn.getExpression();
+ name = cr.toString();
+ }
+ positions.put(name, i++);
+ }
+ for (SortSpecification ss : qe.getOrderBy().getSortSpecifications()) {
+ Expression ex = ss.getExpression();
+ if (!(ex instanceof ColumnReference)) {
+ continue;
+ }
+ ColumnReference cr = (ColumnReference)ex;
+ Integer position = positions.get(cr.toString());
+ if (position != null) {
+ ss.setExpression(new Literal(position, TypeFacility.RUNTIME_TYPES.INTEGER));
+ }
+ }
+ }
+ }
+ return super.translateCommand(command, context);
}
public static class LocateModifier extends FunctionModifier {
@@ -330,67 +358,31 @@
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
Expression expr1 = function.getParameters().get(0);
Expression expr2 = function.getParameters().get(1);
if (function.getParameters().size() > 2) {
Expression expr3 = function.getParameters().get(2);
target.add("position("); //$NON-NLS-1$
- target.addAll(expressionToString(expr1, this.convertModifier));
+ target.add(expr1);
target.add( " in "); //$NON-NLS-1$
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(expr2, this.convertModifier));
+ target.add(expr2);
target.add(","); //$NON-NLS-1$
target.add(expr3);
target.add("))"); //$NON-NLS-1$
}
else {
target.add("position("); //$NON-NLS-1$
- target.addAll(expressionToString(expr1, this.convertModifier));
+ target.add(expr1);
target.add( " in "); //$NON-NLS-1$
- target.addAll(expressionToString(expr2, this.convertModifier));
+ target.add(expr2);
target.add(")"); //$NON-NLS-1$
}
return target;
}
}
- private static List<?> expressionToString(Expression expr, ConvertModifier
modifier) {
- Class tgtType = expr.getType();
- if (tgtType.equals(String.class) && ((expr instanceof Literal) || expr
instanceof ColumnReference)) {
- return Arrays.asList(expr);
- }
- else if (tgtType.equals(String.class) && (expr instanceof Function)) {
-
- Function func = (Function)expr;
- while(true) {
- Expression arg1 = func.getParameters().get(0);
- if ((arg1 instanceof Function) &&
((Function)arg1).getName().equals("convert")) { //$NON-NLS-1$
- func = (Function)arg1;
- }
- else {
- break;
- }
- }
- Expression arg1 = func.getParameters().get(0);
- if (arg1 instanceof ColumnReference) {
- ColumnReference ref = (ColumnReference)func.getParameters().get(0);
- if(Number.class.isAssignableFrom(ref.getType())) {
- ArrayList target = new ArrayList();
- target.add("cast("); //$NON-NLS-1$
- target.add(func.getParameters().get(0));
- target.add(" AS varchar(100))"); //$NON-NLS-1$
- return target;
- }
- else if (String.class.isAssignableFrom(ref.getType())) {
- return Arrays.asList(ref);
- }
- }
- return modifier.translate(func);
- }
- return Arrays.asList("cast(" , expr, " AS varchar(100))");
//$NON-NLS-1$ //$NON-NLS-2$
- }
-
public static class ExtractModifier extends FunctionModifier {
private String type;
public ExtractModifier(String type) {
@@ -413,47 +405,6 @@
}
}
- public static class StringOnlyModifier extends FunctionModifier {
- String funcName;
- ConvertModifier convertModifier;
- public StringOnlyModifier(String name, ConvertModifier converModifier) {
- this.funcName = name;
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add(this.funcName);
- target.add("("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
-
- public static class SubstrModifier extends FunctionModifier {
- ConvertModifier convertModifier;
- public SubstrModifier(ConvertModifier converModifier) {
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(","); //$NON-NLS-1$
- target.add(function.getParameters().get(1));
- if (function.getParameters().size() > 2 ) {
- target.add(","); //$NON-NLS-1$
- target.add(function.getParameters().get(2));
- }
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
-
public static class LeftOrRightFunctionModifier extends FunctionModifier {
private LanguageFactory langFactory;
ConvertModifier convertModifier;
@@ -466,11 +417,11 @@
@Override
public List<?> translate(Function function) {
List<Expression> args = function.getParameters();
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
if (function.getName().equalsIgnoreCase("left")) { //$NON-NLS-1$
//substr(string, 1, length)
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(","); //$NON-NLS-1$
target.add(langFactory.createLiteral(Integer.valueOf(1),
TypeFacility.RUNTIME_TYPES.INTEGER));
target.add(","); //$NON-NLS-1$
@@ -479,10 +430,10 @@
} else if (function.getName().equalsIgnoreCase("right")) {
//$NON-NLS-1$
//substr(case_size, character_length(case_size) -4)
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(",(character_length("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(")-"); //$NON-NLS-1$
target.add(args.get(1));
target.add("+1))"); //$NON-NLS-1$ // offset for 1 based index
@@ -491,22 +442,4 @@
}
}
- public static class UpperOrLowerModifier extends FunctionModifier {
- String funcName;
- ConvertModifier convertModifier;
- public UpperOrLowerModifier(String name, ConvertModifier converModifier) {
- this.funcName = name;
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add(this.funcName);
- target.add("("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
}
Modified:
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
===================================================================
---
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -49,9 +49,13 @@
private static SQLServerExecutionFactory trans = new SQLServerExecutionFactory();
@BeforeClass
- public static void setup() throws TranslatorException {
+ public static void oneTimeSetup() throws TranslatorException {
trans.start();
}
+
+ public void setUp() throws Exception {
+ trans.setDatabaseVersion(SQLServerExecutionFactory.V_2005);
+ }
public String getTestVDB() {
return TranslationHelper.PARTS_VDB;
@@ -143,6 +147,25 @@
output);
}
+ @Test public void testConvertDate() throws Exception {
+ String input = "select stringkey from bqt1.smalla where
BQT1.SmallA.DateValue IN (convert('2000-01-12', date),
convert('2000-02-02', date))"; //$NON-NLS-1$
+ String output = "SELECT SmallA.StringKey FROM SmallA WHERE SmallA.DateValue
IN (CAST('2000-01-12 00:00:00.0' AS DATETIME), CAST('2000-02-02
00:00:00.0' AS DATETIME))"; //$NON-NLS-1$
+
+ helpTestVisitor(getBQTVDB(),
+ input,
+ output);
+ }
+
+ @Test public void testConvertDate2008() throws Exception {
+ trans.setDatabaseVersion(SQLServerExecutionFactory.V_2008);
+ String input = "select stringkey from bqt1.smalla where
BQT1.SmallA.DateValue IN (convert('2000-01-12', date),
convert('2000-02-02', date))"; //$NON-NLS-1$
+ String output = "SELECT SmallA.StringKey FROM SmallA WHERE SmallA.DateValue
IN (CAST('2000-01-12' AS DATE), CAST('2000-02-02' AS DATE))";
//$NON-NLS-1$
+
+ helpTestVisitor(getBQTVDB(),
+ input,
+ output);
+ }
+
@Test public void testUniqueidentifier() throws Exception {
MetadataStore metadataStore = new MetadataStore();
Schema foo = RealMetadataFactory.createPhysicalModel("foo",
metadataStore); //$NON-NLS-1$
Modified:
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java
===================================================================
---
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -31,6 +31,8 @@
import org.junit.BeforeClass;
import org.junit.Test;
+import org.teiid.cdk.api.TranslationUtility;
+import org.teiid.language.Command;
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.In;
@@ -82,35 +84,61 @@
@Test public void testIntegerToString() throws Exception {
String input = "SELECT lcase(bigdecimalvalue) FROM BQT1.SMALLA";
- String output = "SELECT LOWER(cast(SmallA.BigDecimalValue AS varchar(100)))
FROM SmallA";
+ String output = "SELECT LOWER(cast(SmallA.BigDecimalValue AS varchar(4000)))
FROM SmallA";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output,
TRANSLATOR);
}
@Test public void testSubString() throws Exception {
String input = "SELECT intkey FROM BQT1.SmallA WHERE
SUBSTRING(BQT1.SmallA.IntKey, 1) = '1' ORDER BY intkey";
- String output = "SELECT SmallA.IntKey FROM SmallA WHERE
substr(cast(SmallA.IntKey AS varchar(100)),1) = '1' ORDER BY SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE
substr(cast(SmallA.IntKey AS varchar(4000)), 1) = '1' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output,
TRANSLATOR);
}
@Test public void testSubString2() throws Exception {
String input = "SELECT intkey FROM BQT1.SmallA WHERE
SUBSTRING(BQT1.SmallA.IntKey, 1, 2) = '1' ORDER BY intkey";
- String output = "SELECT SmallA.IntKey FROM SmallA WHERE
substr(cast(SmallA.IntKey AS varchar(100)),1,2) = '1' ORDER BY
SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE
substr(cast(SmallA.IntKey AS varchar(4000)), 1, 2) = '1' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output,
TRANSLATOR);
}
@Test public void testDateToString() throws Exception {
String input = "SELECT intkey, UPPER(timevalue) AS UPPER FROM BQT1.SmallA
ORDER BY intkey";
- String output = "SELECT SmallA.IntKey, UPPER(cast(cast(SmallA.TimeValue AS
FORMAT 'HH:MI:SS') AS VARCHAR(9))) AS UPPER FROM SmallA ORDER BY
SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey, UPPER(cast(cast(SmallA.TimeValue AS
FORMAT 'HH:MI:SS') AS VARCHAR(9))) AS UPPER FROM SmallA ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output,
TRANSLATOR);
}
@Test public void testLocate() throws Exception {
String input = "SELECT INTKEY, BIGDECIMALVALUE FROM BQT1.SmallA WHERE
LOCATE('-', BIGDECIMALVALUE) = 1 ORDER BY intkey";
- String output = "SELECT SmallA.IntKey, SmallA.BigDecimalValue FROM SmallA
WHERE position('-' in cast(SmallA.BigDecimalValue AS varchar(100))) = 1 ORDER BY
SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey, SmallA.BigDecimalValue FROM SmallA
WHERE position('-' in cast(SmallA.BigDecimalValue AS varchar(4000))) = 1 ORDER BY
1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output,
TRANSLATOR);
}
+ @Test public void testPositionalOrderBy() throws Exception {
+ String input = "SELECT INTKEY, BIGDECIMALVALUE FROM BQT1.SmallA ORDER BY
intkey";
+ String output = "SELECT g_0.IntKey AS c_0, g_0.BigDecimalValue AS c_1 FROM
SmallA AS g_0 ORDER BY 1";
+
+ TranslationUtility tu =
TranslationHelper.getTranslationUtility(TranslationHelper.BQT_VDB, null);
+ Command command = tu.parseCommand(input, true, true);
+ TranslationHelper.helpTestVisitor(output, TRANSLATOR, command);
+ }
+ @Test public void testPositionalOrderByUnion() throws Exception {
+ String input = "SELECT a as b, b as a from (SELECT intkey as a, stringkey as
b from BQT1.smalla union SELECT intkey as a, stringkey as b from BQT1.smalla) as x order
by a";
+ String output = "SELECT v_0.c_0, v_0.c_1 FROM (SELECT g_1.IntKey AS c_0,
g_1.StringKey AS c_1 FROM SmallA AS g_1 UNION SELECT g_0.IntKey AS c_0, g_0.StringKey AS
c_1 FROM SmallA AS g_0) AS v_0 ORDER BY 2";
+
+ TranslationUtility tu =
TranslationHelper.getTranslationUtility(TranslationHelper.BQT_VDB, null);
+ Command command = tu.parseCommand(input, true, true);
+ TranslationHelper.helpTestVisitor(output, TRANSLATOR, command);
+ }
+
+ @Test public void testPositionalOrderByUnion1() throws Exception {
+ String input = "SELECT a as b from (SELECT intkey as a, stringkey as b from
BQT1.smalla union SELECT intkey as a, stringkey as b from BQT1.smalla) as x order by
x.b";
+ String output = "SELECT v_0.c_0 FROM (SELECT g_1.IntKey AS c_0,
g_1.StringKey AS c_1 FROM SmallA AS g_1 UNION SELECT g_0.IntKey AS c_0, g_0.StringKey AS
c_1 FROM SmallA AS g_0) AS v_0 ORDER BY v_0.c_1";
+
+ TranslationUtility tu =
TranslationHelper.getTranslationUtility(TranslationHelper.BQT_VDB, null);
+ Command command = tu.parseCommand(input, true, true);
+ TranslationHelper.helpTestVisitor(output, TRANSLATOR, command);
+ }
+
@Test public void testByteToString() throws Exception {
helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class),
"string", "cast(1 AS varchar(4000))");
}
@@ -194,13 +222,13 @@
@Test public void testRightFunction() throws Exception {
String input = "SELECT INTKEY, FLOATNUM FROM BQT1.SmallA WHERE right(FLOATNUM, 2)
<> 0 ORDER BY INTKEY";
- String out = "SELECT SmallA.IntKey, SmallA.FloatNum FROM SmallA WHERE
substr(cast(SmallA.FloatNum AS varchar(100)),(character_length(cast(SmallA.FloatNum AS
varchar(100)))-2+1)) <> '0' ORDER BY SmallA.IntKey";
+ String out = "SELECT SmallA.IntKey, SmallA.FloatNum FROM SmallA WHERE
substr(cast(SmallA.FloatNum AS varchar(4000)),(character_length(cast(SmallA.FloatNum AS
varchar(4000)))-2+1)) <> '0' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, null, input, out,
TRANSLATOR);
}
@Test public void testLocateFunction() throws Exception {
String input = "SELECT INTKEY, STRINGKEY, SHORTVALUE FROM BQT1.SmallA WHERE
(LOCATE(0, STRINGKEY) = 2) OR (LOCATE(2, SHORTVALUE, 4) = 6) ORDER BY intkey";
- String out = "SELECT SmallA.IntKey, SmallA.StringKey, SmallA.ShortValue FROM
SmallA WHERE position('0' in SmallA.StringKey) = 2 OR position('2' in
substr(cast(SmallA.ShortValue AS varchar(100)),4)) = 6 ORDER BY SmallA.IntKey";
+ String out = "SELECT SmallA.IntKey, SmallA.StringKey, SmallA.ShortValue FROM
SmallA WHERE position('0' in SmallA.StringKey) = 2 OR position('2' in
substr(cast(SmallA.ShortValue AS varchar(4000)),4)) = 6 ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, null, input, out,
TRANSLATOR);
}
}
Modified:
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
===================================================================
---
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2011-07-22
16:26:08 UTC (rev 3327)
@@ -250,10 +250,9 @@
<code>boolean</code>
</entry>
<entry>
- <para>A change was made in JDBC4 so that when an
'Alias' is used it will
- now be returned as the label. Prior to this, it was returned as
- the name. Setting this property to false will enable
- backwards compatibility when JDBC3 and older support is still required.
+ <para>A change was made in JDBC4 to return unaliased
column names as the ResultSetMetadata column name.
+ Prior to this, if a column alias were used it was returned as
the column name. Setting this property to false will enable
+ backwards compatibility when JDBC3 and older support is still required. Defaults
to true.
</para>
</entry>
</row>
Modified:
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml
===================================================================
---
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml 2011-07-22
16:26:08 UTC (rev 3327)
@@ -175,11 +175,7 @@
<code>JDBC4COLUMNNAMEANDLABELSEMANTICS /
useJDBC4ColumnNameAndLabelSemantics</code>
</entry>
<entry>
- <para>A change was made in JDBC4 so that when an
'Alias' is used it will.
- now be returned as the label. Prior to this, it was returned as
- the name. Setting this property to false will enable
- backwards compatibility when JDBC3 and older support is still required.
- </para>
+ <para>Same as the connection property.</para>
</entry>
</row>
</tbody>
Modified: trunk/engine/pom.xml
===================================================================
--- trunk/engine/pom.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/pom.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -78,14 +78,8 @@
<dependency>
<groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
+ <artifactId>saxonhe</artifactId>
</dependency>
-
- <dependency>
- <groupId>net.sourceforge.saxon</groupId>
- <classifier>dom</classifier>
- <artifactId>saxon</artifactId>
- </dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
@@ -106,4 +100,4 @@
</dependencies>
-</project>
\ No newline at end of file
+</project>
Modified:
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -115,6 +115,7 @@
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
+import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.translator.TranslatorException;
@@ -179,9 +180,9 @@
/* Query */
Select translate(Query query) {
- List symbols = query.getSelect().getSymbols();
+ List<SelectSymbol> symbols = query.getSelect().getSymbols();
List<DerivedColumn> translatedSymbols = new
ArrayList<DerivedColumn>(symbols.size());
- for (Iterator i = symbols.iterator(); i.hasNext();) {
+ for (Iterator<SelectSymbol> i = symbols.iterator(); i.hasNext();) {
SingleElementSymbol symbol = (SingleElementSymbol)i.next();
String alias = null;
if(symbol instanceof AliasSymbol) {
@@ -375,7 +376,7 @@
In translate(SetCriteria criteria) {
Collection expressions = criteria.getValues();
- List translatedExpressions = new ArrayList();
+ List<org.teiid.language.Expression> translatedExpressions = new
ArrayList<org.teiid.language.Expression>();
for (Iterator i = expressions.iterator(); i.hasNext();) {
translatedExpressions.add(translate((Expression)i.next()));
}
@@ -423,13 +424,13 @@
return new SubqueryComparison(translate(criteria.getLeftExpression()),
operator,
quantifier,
- translate((QueryCommand)criteria.getCommand()));
+ translate(criteria.getCommand()));
}
SubqueryIn translate(SubquerySetCriteria criteria) {
return new SubqueryIn(translate(criteria.getExpression()),
criteria.isNegated(),
- translate((QueryCommand)criteria.getCommand()));
+ translate(criteria.getCommand()));
}
Not translate(NotCriteria criteria) {
@@ -462,7 +463,7 @@
if(items.get(i).isUnrelated() || (!set && symbol instanceof
ElementSymbol)){
orderByItem = new SortSpecification(direction, translate(symbol));
} else {
- orderByItem = new SortSpecification(direction, new ColumnReference(null,
symbol.getOutputName(), null, symbol.getType()));
+ orderByItem = new SortSpecification(direction, new ColumnReference(null,
SingleElementSymbol.getShortName(symbol.getOutputName()), null, symbol.getType()));
}
orderByItem.setNullOrdering(items.get(i).getNullOrdering());
translatedItems.add(orderByItem);
@@ -558,7 +559,7 @@
}
ColumnReference translate(ElementSymbol symbol) {
- ColumnReference element = new ColumnReference(translate(symbol.getGroupSymbol()),
symbol.getOutputName(), null, symbol.getType());
+ ColumnReference element = new ColumnReference(translate(symbol.getGroupSymbol()),
SingleElementSymbol.getShortName(symbol.getOutputName()), null, symbol.getType());
if (element.getTable().getMetadataObject() == null) {
return element;
}
@@ -746,10 +747,10 @@
/* Batched Updates */
BatchedUpdates translate(BatchedUpdateCommand command) {
- List updates = command.getUpdateCommands();
+ List<Command> updates = command.getUpdateCommands();
List<org.teiid.language.Command> translatedUpdates = new
ArrayList<org.teiid.language.Command>(updates.size());
- for (Iterator i = updates.iterator(); i.hasNext();) {
- translatedUpdates.add(translate((Command)i.next()));
+ for (Iterator<Command> i = updates.iterator(); i.hasNext();) {
+ translatedUpdates.add(translate(i.next()));
}
return new BatchedUpdates(translatedUpdates);
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -26,7 +26,6 @@
import javax.resource.spi.work.WorkEvent;
import javax.resource.spi.work.WorkListener;
-import org.teiid.core.TeiidRuntimeException;
import org.teiid.logging.LogManager;
@@ -43,23 +42,14 @@
private ThreadState threadState = ThreadState.MORE_WORK;
private volatile boolean isProcessing;
- private Thread callingThread;
- public AbstractWorkItem(Thread callingThread) {
- this.callingThread = callingThread;
- }
-
public void run() {
- do {
- startProcessing();
- try {
- process();
- } finally {
- if (!endProcessing()) {
- break;
- }
- }
- } while (!isDoneProcessing());
+ startProcessing();
+ try {
+ process();
+ } finally {
+ endProcessing();
+ }
}
synchronized ThreadState getThreadState() {
@@ -79,10 +69,7 @@
this.threadState = ThreadState.WORKING;
}
- /**
- * @return true if processing should be continued
- */
- final private synchronized boolean endProcessing() {
+ private synchronized void endProcessing() {
isProcessing = false;
logTrace("end processing"); //$NON-NLS-1$
switch (this.threadState) {
@@ -92,21 +79,20 @@
this.threadState = ThreadState.DONE;
} else {
this.threadState = ThreadState.IDLE;
- return pauseProcessing();
+ pauseProcessing();
}
break;
case MORE_WORK:
if (isDoneProcessing()) {
logTrace("done processing - ignoring more"); //$NON-NLS-1$
this.threadState = ThreadState.DONE;
- } else if (this.callingThread == null) {
- resumeProcessing();
+ } else {
+ resumeProcessing();
}
break;
default:
throw new IllegalStateException("Should not END on " +
this.threadState); //$NON-NLS-1$
}
- return this.callingThread != null;
}
protected boolean isIdle() {
@@ -117,8 +103,9 @@
moreWork(true);
}
- final protected synchronized void moreWork(boolean ignoreDone) {
+ protected synchronized void moreWork(boolean ignoreDone) {
logTrace("more work"); //$NON-NLS-1$
+ this.notifyAll();
switch (this.threadState) {
case WORKING:
this.threadState = ThreadState.MORE_WORK;
@@ -127,15 +114,7 @@
break;
case IDLE:
this.threadState = ThreadState.MORE_WORK;
- if (this.callingThread != null) {
- if (this.callingThread == Thread.currentThread()) {
- run(); //restart with the calling thread
- } else {
- this.notifyAll(); //notify the waiting caller
- }
- } else {
- resumeProcessing();
- }
+ resumeProcessing();
break;
default:
if (!ignoreDone) {
@@ -151,33 +130,8 @@
protected abstract void process();
- protected boolean pauseProcessing() {
- if (this.callingThread != null && !shouldPause()) {
- return false;
- }
- while (this.callingThread != null && this.getThreadState() == ThreadState.IDLE)
{
- try {
- this.wait(); //the lock should already be held
- } catch (InterruptedException e) {
- interrupted(e);
- }
- }
- return this.callingThread != null;
+ protected void pauseProcessing() {
}
-
- /**
- * only called for synch processing
- */
- protected boolean shouldPause() {
- return false;
- }
-
- /**
- * only called for synch processing
- */
- protected void interrupted(InterruptedException e) {
- throw new TeiidRuntimeException(e);
- }
protected abstract void resumeProcessing();
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -93,9 +93,11 @@
private long creationTime = System.currentTimeMillis();
private DQPWorkContext workContext = DQPWorkContext.getWorkContext();
private List<CompletionListener<T>> completionListeners = new
LinkedList<CompletionListener<T>>();
+ private String parentName;
public FutureWork(final Callable<T> processor, int priority) {
super(processor);
+ this.parentName = Thread.currentThread().getName();
this.priority = priority;
}
@@ -105,6 +107,12 @@
}
@Override
+ public void run() {
+ LogManager.logDetail(LogConstants.CTX_DQP, "Running task for parent thread",
parentName); //$NON-NLS-1$
+ super.run();
+ }
+
+ @Override
public int getPriority() {
return priority;
}
@@ -344,6 +352,7 @@
}
}
if (runInThread) {
+ workItem.useCallingThread = true;
workItem.run();
}
return resultsFuture;
@@ -721,6 +730,8 @@
processorDataManager.setMetadataRepository(metadataRepository);
dataTierMgr = new TempTableDataManager(processorDataManager, this.bufferManager,
this.processWorkerPool, this.rsCache, this.matTables, this.cacheFactory);
dataTierMgr.setEventDistributor(eventDistributor);
+
+ LogManager.logDetail(LogConstants.CTX_DQP, "DQPCore started
maxThreads", this.config.getMaxThreads(), "maxActivePlans",
this.maxActivePlans, "source concurrency", this.userRequestSourceConcurrency);
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void setBufferService(BufferService service) {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -188,11 +188,8 @@
}
public void runInContext(final Runnable runnable) {
- DQPWorkContext.setWorkContext(this);
- boolean associated = false;
- if (securityHelper != null && this.getSubject() != null) {
- associated = securityHelper.assosiateSecurityContext(this.getSecurityDomain(),
this.getSecurityContext());
- }
+ DQPWorkContext previous = DQPWorkContext.getWorkContext();
+ boolean associated = attachDQPWorkContext();
try {
runnable.run();
} finally {
@@ -200,9 +197,21 @@
securityHelper.clearSecurityContext(this.getSecurityDomain());
}
DQPWorkContext.releaseWorkContext();
+ if (previous != null) {
+ previous.attachDQPWorkContext();
+ }
}
}
+ private boolean attachDQPWorkContext() {
+ DQPWorkContext.setWorkContext(this);
+ boolean associated = false;
+ if (securityHelper != null && this.getSubject() != null) {
+ associated = securityHelper.assosiateSecurityContext(this.getSecurityDomain(),
this.getSecurityContext());
+ }
+ return associated;
+ }
+
public HashMap<String, DataPolicy> getAllowedDataPolicies() {
if (this.policies == null) {
this.policies = new HashMap<String, DataPolicy>();
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -162,8 +162,10 @@
/**The time when command begins processing on the server.*/
private long processingTimestamp = System.currentTimeMillis();
+ protected boolean useCallingThread;
+ private volatile boolean hasThread;
+
public RequestWorkItem(DQPCore dqpCore, RequestMessage requestMsg, Request request,
ResultsReceiver<ResultsMessage> receiver, RequestID requestID, DQPWorkContext
workContext) {
- super(workContext.useCallingThread() || requestMsg.isSync() ? Thread.currentThread()
: null);
this.requestMsg = requestMsg;
this.requestID = requestID;
this.processorTimeslice = dqpCore.getProcessorTimeSlice();
@@ -196,24 +198,65 @@
protected boolean isDoneProcessing() {
return isClosed;
}
+
+ @Override
+ public void run() {
+ hasThread = true;
+ try {
+ while (!isDoneProcessing()) {
+ super.run();
+ if (!useCallingThread) {
+ break;
+ }
+ //should use the calling thread
+ synchronized (this) {
+ if (this.resultsReceiver == null) {
+ break; //allow results to be processed by calling thread
+ }
+ if (this.getThreadState() == ThreadState.MORE_WORK) {
+ continue;
+ }
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ try {
+ requestCancel();
+ } catch (TeiidComponentException e1) {
+ throw new TeiidRuntimeException(e1);
+ }
+ }
+ }
+ }
+ } finally {
+ hasThread = false;
+ }
+ }
@Override
protected void resumeProcessing() {
- if (doneProducingBatches && !closeRequested && !isCanceled) {
- this.run(); // just run in the IO thread
- } else {
+ if (!this.useCallingThread) {
dqpCore.addWork(this);
}
}
- @Override
- protected void interrupted(InterruptedException e) {
- try {
- this.requestCancel();
- } catch (TeiidComponentException e1) {
- throw new TeiidRuntimeException(e1);
+ /**
+ * Special call from request threads to allow resumption of processing by
+ * the calling thread.
+ */
+ public void doMoreWork() {
+ boolean run = false;
+ synchronized (this) {
+ moreWork();
+ if (!useCallingThread || this.getThreadState() != ThreadState.MORE_WORK) {
+ return;
+ }
+ run = !hasThread;
}
- super.interrupted(e);
+ if (run) {
+ //run outside of the lock
+ LogManager.logDetail(LogConstants.CTX_DQP, "Restarting processing using the
calling thread", requestID); //$NON-NLS-1$
+ run();
+ }
}
@Override
@@ -293,7 +336,7 @@
}
private void suspend() {
- if (this.transactionState == TransactionState.ACTIVE &&
this.transactionContext.getTransaction() != null) {
+ if ((this.transactionState != TransactionState.NONE) &&
this.transactionContext.getTransaction() != null) {
try {
this.transactionService.suspend(this.transactionContext);
} catch (XATransactionException e) {
@@ -650,12 +693,6 @@
return new TeiidProcessingException(exception, SQLStates.QUERY_CANCELED,
exception.getMessage());
}
- @Override
- protected boolean shouldPause() {
- //if we are waiting on results it's ok to pause
- return this.resultsReceiver != null;
- }
-
private static List<ParameterInfo> getParameterInfo(StoredProcedure procedure)
{
List<ParameterInfo> paramInfos = new ArrayList<ParameterInfo>();
@@ -750,12 +787,12 @@
if (!this.doneProducingBatches) {
this.requestCancel(); //pending work should be canceled for fastest clean up
}
- this.moreWork();
+ this.doMoreWork();
}
public void requestMore(int batchFirst, int batchLast,
ResultsReceiver<ResultsMessage> receiver) {
this.requestResults(batchFirst, batchLast, receiver);
- this.moreWork();
+ this.doMoreWork();
}
public void closeAtomicRequest(AtomicRequestID atomicRequestId) {
Modified: trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -25,8 +25,8 @@
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -214,7 +214,7 @@
*/
public Map<MappingNodeConstants.Properties, Object> getNodeProperties(){
if(nodeProperties == null) {
- nodeProperties = new HashMap<MappingNodeConstants.Properties,
Object>();
+ nodeProperties = new LinkedHashMap<MappingNodeConstants.Properties,
Object>();
}
return nodeProperties;
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -43,7 +43,6 @@
public static final int SET_OP = 1<<8;
public static final int NULL = 1<<9;
public static final int TUPLE_LIMIT = 1<<10;
- public static final int WITH = 1<<11;
}
/**
@@ -64,7 +63,6 @@
case NodeConstants.Types.SET_OP: return "SetOperation";
//$NON-NLS-1$
case NodeConstants.Types.NULL: return "Null";
//$NON-NLS-1$
case NodeConstants.Types.TUPLE_LIMIT: return "TupleLimit";
//$NON-NLS-1$
- case NodeConstants.Types.WITH: return "With"; //$NON-NLS-1$
default: return "Unknown: " + type;
//$NON-NLS-1$
}
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -37,7 +37,6 @@
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
-import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.util.Assertion;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -50,17 +49,21 @@
import org.teiid.query.resolver.util.AccessPattern;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.CompoundCriteria;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.GroupBy;
import org.teiid.query.sql.lang.OrderBy;
+import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.lang.QueryCommand;
import org.teiid.query.sql.lang.Select;
import org.teiid.query.sql.lang.StoredProcedure;
+import org.teiid.query.sql.symbol.AliasSymbol;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.ExpressionSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
@@ -125,15 +128,15 @@
}
static boolean canConvertAccessPatterns(PlanNode sourceNode) {
- List accessPatterns =
(List)sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
+ List<AccessPattern> accessPatterns =
(List)sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
if (accessPatterns == null) {
return true;
}
SymbolMap symbolMap =
(SymbolMap)sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
- for (Iterator i = accessPatterns.iterator(); i.hasNext();) {
- AccessPattern ap = (AccessPattern)i.next();
- for (Iterator elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<AccessPattern> i = accessPatterns.iterator(); i.hasNext();)
{
+ AccessPattern ap = i.next();
+ for (Iterator<ElementSymbol> elems = ap.getUnsatisfied().iterator();
elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap.asMap());
if (ElementCollectorVisitor.getElements(mapped, true).isEmpty()) {
return false;
@@ -154,15 +157,15 @@
if (accessPatterns != null) {
for (AccessPattern ap : accessPatterns) {
Set<ElementSymbol> newElements = new
HashSet<ElementSymbol>();
- for (Iterator elems = ap.getUnsatisfied().iterator(); elems.hasNext();)
{
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<ElementSymbol> elems =
ap.getUnsatisfied().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap);
newElements.addAll(ElementCollectorVisitor.getElements(mapped,
true));
}
ap.setUnsatisfied(newElements);
Set<ElementSymbol> newHistory = new
HashSet<ElementSymbol>();
- for (Iterator elems = ap.getCurrentElements().iterator();
elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<ElementSymbol> elems =
ap.getCurrentElements().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap);
newHistory.addAll(ElementCollectorVisitor.getElements(mapped,
true));
}
@@ -233,6 +236,11 @@
List<SingleElementSymbol> projectedSymbols =
(List<SingleElementSymbol>)node.getProperty(NodeConstants.Info.PROJECT_COLS);
Select select = new Select(projectedSymbols);
ExpressionMappingVisitor.mapExpressions(select, symbolMap);
+ if (rewrite) {
+ for (LanguageObject expr : select.getSymbols()) {
+ rewriteSingleElementSymbol(metadata, (SingleElementSymbol) expr);
+ }
+ }
node.setProperty(NodeConstants.Info.PROJECT_COLS, select.getSymbols());
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(select, groups);
@@ -257,6 +265,11 @@
} else if(type == NodeConstants.Types.SORT) {
OrderBy orderBy = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
ExpressionMappingVisitor.mapExpressions(orderBy, symbolMap);
+ if (rewrite) {
+ for (OrderByItem item : orderBy.getOrderByItems()) {
+ rewriteSingleElementSymbol(metadata, item.getSymbol());
+ }
+ }
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(orderBy, groups);
}
@@ -278,6 +291,25 @@
convertAccessPatterns(symbolMap, node);
}
}
+
+ private static void rewriteSingleElementSymbol(
+ QueryMetadataInterface metadata, SingleElementSymbol ses) throws QueryPlannerException
{
+ try {
+ if (ses instanceof AliasSymbol) {
+ ses = ((AliasSymbol)ses).getSymbol();
+ }
+ if (ses instanceof ExpressionSymbol) {
+ ExpressionSymbol es = (ExpressionSymbol)ses;
+ if (es.getExpression() != null) {
+ es.setExpression(QueryRewriter.rewriteExpression(es.getExpression(), null, null,
metadata));
+ }
+ }
+ } catch(TeiidProcessingException e) {
+ throw new QueryPlannerException(e,
QueryPlugin.Util.getString("ERR.015.004.0023", ses)); //$NON-NLS-1$
+ } catch (TeiidComponentException e) {
+ throw new QueryPlannerException(e,
QueryPlugin.Util.getString("ERR.015.004.0023", ses)); //$NON-NLS-1$
+ }
+ }
private static Expression convertExpression(Expression expression, Map symbolMap) {
@@ -314,7 +346,7 @@
} catch(TeiidProcessingException e) {
throw new QueryPlannerException(e,
QueryPlugin.Util.getString("ERR.015.004.0023", criteria)); //$NON-NLS-1$
} catch (TeiidComponentException e) {
- throw new TeiidRuntimeException(e);
+ throw new QueryPlannerException(e,
QueryPlugin.Util.getString("ERR.015.004.0023", criteria)); //$NON-NLS-1$
}
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -419,11 +419,11 @@
result.type = crit.getClass();
result.not = exists.isNegated();
//the correlations can only be in where (if no group by or aggregates) or having
- result.query = (Query)exists.getCommand();
result.mergeJoin = exists.getSubqueryHint().isMergeJoin();
if (!UNNEST && !result.mergeJoin) {
return result;
}
+ result.query = (Query)exists.getCommand();
}
return result;
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -52,6 +52,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.Transform;
import org.teiid.core.util.Assertion;
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.SQLConstants.NonReserved;
@@ -148,7 +149,6 @@
import org.teiid.query.sql.symbol.Reference;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
-import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.symbol.AggregateSymbol.Type;
import org.teiid.query.sql.util.SymbolMap;
@@ -240,6 +240,7 @@
* @throws QueryValidatorException
*/
private Command rewriteCommand(Command command, boolean removeOrderBy) throws
TeiidComponentException, TeiidProcessingException{
+ boolean oldRewriteAggs = rewriteAggs;
QueryMetadataInterface oldMetadata = metadata;
CreateUpdateProcedureCommand oldProcCommand = procCommand;
@@ -299,6 +300,7 @@
break;
}
+ this.rewriteAggs = oldRewriteAggs;
this.metadata = oldMetadata;
this.procCommand = oldProcCommand;
return command;
@@ -605,9 +607,9 @@
From from = query.getFrom();
if(from != null){
List<FromClause> clauses = new
ArrayList<FromClause>(from.getClauses().size());
- Iterator clauseIter = from.getClauses().iterator();
+ Iterator<FromClause> clauseIter = from.getClauses().iterator();
while(clauseIter.hasNext()) {
- clauses.add( rewriteFromClause(query, (FromClause) clauseIter.next()) );
+ clauses.add( rewriteFromClause(query, clauseIter.next()) );
}
from.setClauses(clauses);
} else {
@@ -765,6 +767,7 @@
*/
private Query rewriteGroupBy(Query query) throws TeiidComponentException,
TeiidProcessingException {
if (query.getGroupBy() == null) {
+ rewriteAggs = false;
return query;
}
if (isDistinctWithGroupBy(query)) {
@@ -811,11 +814,11 @@
try {
PostOrderNavigator.doVisit(obj, visitor);
} catch (TeiidRuntimeException err) {
- if (err.getChild() instanceof TeiidComponentException) {
- throw (TeiidComponentException)err.getChild();
+ if (err.getCause() instanceof TeiidComponentException) {
+ throw (TeiidComponentException)err.getCause();
}
- if (err.getChild() instanceof TeiidProcessingException) {
- throw (TeiidProcessingException)err.getChild();
+ if (err.getCause() instanceof TeiidProcessingException) {
+ throw (TeiidProcessingException)err.getCause();
}
throw err;
}
@@ -1552,6 +1555,7 @@
private BigDecimal BIG_DECIMAL_ZERO = new BigDecimal("0"); //$NON-NLS-1$
private Short SHORT_ZERO = new Short((short)0);
private Byte BYTE_ZERO = new Byte((byte)0);
+ private boolean rewriteAggs = true;
/**
* @param criteria
@@ -2246,6 +2250,9 @@
expression.setAggregateFunction(Type.MAX);
}
}
+ if (rewriteAggs && expression.getExpression() != null &&
EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
+ return expression.getExpression();
+ }
if (expression.getExpression() != null && expression.getCondition() != null
&& !expression.respectsNulls()) {
Expression cond = expression.getCondition();
Expression ex = expression.getExpression();
@@ -2414,17 +2421,44 @@
}
function.setArgs(newArgs);
- if( FunctionLibrary.isConvert(function) &&
- newArgs[1] instanceof Constant) {
-
- Class srcType = newArgs[0].getType();
- String tgtTypeName = (String) ((Constant)newArgs[1]).getValue();
- Class tgtType = DataTypeManager.getDataTypeClass(tgtTypeName);
+ if( FunctionLibrary.isConvert(function)) {
+ Class<?> srcType = newArgs[0].getType();
+ Class<?> tgtType = function.getType();
if(srcType != null && tgtType != null &&
srcType.equals(tgtType)) {
- return newArgs[0];
+ return newArgs[0]; //unnecessary conversion
}
-
+
+ if (!(newArgs[0] instanceof Function) || tgtType ==
DataTypeManager.DefaultDataClasses.OBJECT) {
+ return function;
+ }
+ Function nested = (Function) newArgs[0];
+ if (!FunctionLibrary.isConvert(nested)) {
+ return function;
+ }
+ Class<?> nestedType = nested.getArgs()[0].getType();
+
+ Transform t = DataTypeManager.getTransform(nestedType, nested.getType());
+ if (t.isExplicit()) {
+ //explicit conversions are required
+ return function;
+ }
+ if (DataTypeManager.getTransform(nestedType, tgtType) == null) {
+ //no direct conversion exists
+ return function;
+ }
+ //can't remove a convert that would alter the lexical form
+ if (tgtType == DataTypeManager.DefaultDataClasses.STRING &&
+ (nestedType == DataTypeManager.DefaultDataClasses.BOOLEAN
+ || nestedType == DataTypeManager.DefaultDataClasses.DATE
+ || nestedType == DataTypeManager.DefaultDataClasses.TIME
+ || tgtType == DataTypeManager.DefaultDataClasses.BIG_DECIMAL
+ || tgtType == DataTypeManager.DefaultDataClasses.FLOAT
+ || (tgtType == DataTypeManager.DefaultDataClasses.DOUBLE && srcType !=
DataTypeManager.DefaultDataClasses.FLOAT))) {
+ return function;
+ }
+ //nested implicit transform is not needed
+ return rewriteExpressionDirect(ResolverUtil.getConversion(nested.getArgs()[0],
DataTypeManager.getDataTypeName(nestedType), DataTypeManager.getDataTypeName(tgtType),
false, funcLibrary));
}
//convert DECODESTRING function to CASE expression
@@ -2702,7 +2736,7 @@
select.setSymbols(select.getProjectedSymbols());
- List<SelectSymbol> symbols = select.getSymbols();
+ List symbols = select.getSymbols();
HashSet<String> uniqueNames = new HashSet<String>();
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -30,7 +30,7 @@
import org.teiid.query.sql.visitor.SQLStringVisitor;
/**
- * Represents XMLATTRIBUTES name value pairs
+ * Represents query string name value pairs
*/
public class QueryString implements Expression {
Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -37,6 +37,8 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.language.SQLConstants;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
@@ -96,6 +98,7 @@
public synchronized MatState setState(MatState state, Boolean valid, Long timestamp) {
MatState oldState = this.state;
+ LogManager.logDetail(LogConstants.CTX_MATVIEWS, this, "setting matState to",
state, valid, timestamp, "old values", oldState, this.valid); //$NON-NLS-1$
//$NON-NLS-2$
if (valid != null) {
this.valid = valid;
}
Modified: trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -404,7 +404,7 @@
String groupName = es.getGroupSymbol().getCanonicalName();
UpdateMapping info = updateInfo.updatableGroups.get(groupName);
if (es.getGroupSymbol().getDefinition() != null) {
- ElementSymbol clone = (ElementSymbol)es.clone();
+ ElementSymbol clone = es.clone();
clone.setOutputName(null);
clone.getGroupSymbol().setName(clone.getGroupSymbol().getNonCorrelationName());
clone.getGroupSymbol().setDefinition(null);
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -115,7 +115,7 @@
* @return the unique number identifying this document within the name pool
*/
- public int getDocumentNumber() {
+ public long getDocumentNumber() {
return documentNumber;
}
@@ -124,12 +124,16 @@
*
* @param id
* the required ID value
+ * @param getParent
+ * true if running the element-with-id() function rather than the id()
+ * function; the difference is that in the case of an element of type xs:ID,
+ * the parent of the element should be returned, not the element itself.
* @return the element with the given ID, or null if there is no such ID
* present (or if the parser has not notified attributes as being of
* type ID).
*/
- public NodeInfo selectID(String id) {
+ public NodeInfo selectID(String id, boolean getParent) {
if (idIndex == null) {
Element elem;
switch (nodeKind) {
@@ -145,7 +149,14 @@
idIndex = new HashMap(50);
buildIDIndex(elem);
}
- return (NodeInfo) idIndex.get(id);
+
+ NodeInfo result = (NodeInfo) idIndex.get(id);
+
+ if (result != null && getParent && result.isId() &&
result.getStringValue().equals(id)) {
+ result = result.getParent();
+ }
+
+ return result ;
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -160,6 +160,14 @@
}
/**
+ * Get the real XOM node, to implement the VirtualNode interface
+ */
+
+ public Object getRealNode() {
+ return node;
+ }
+
+ /**
* Get the name pool for this node
*
* @return the NamePool
@@ -799,7 +807,7 @@
* free-standing orphan node, just return the hashcode.
*/
- public int getDocumentNumber() {
+ public long getDocumentNumber() {
return docWrapper.getDocumentNumber();
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -256,6 +256,7 @@
public void close() throws XPathException {
reciever.close();
+ super.close();
}
public void comment(CharSequence content, int locationId, int properties)
@@ -265,6 +266,7 @@
public void endDocument() throws XPathException {
reciever.endDocument();
+ super.endDocument() ;
}
public void endElement() throws XPathException {
@@ -285,6 +287,7 @@
}
public void open() throws XPathException {
+ super.open();
reciever.open();
}
@@ -295,10 +298,12 @@
public void setPipelineConfiguration(PipelineConfiguration config) {
reciever.setPipelineConfiguration(config);
+ super.setPipelineConfiguration(config);
}
public void setSystemId(String systemId) {
reciever.setSystemId(systemId);
+ super.setSystemId(systemId);
}
public void setUnparsedEntity(String name, String systemID,
@@ -311,6 +316,7 @@
}
public void startDocument(int properties) throws XPathException {
+ super.startDocument(properties);
reciever.startDocument(properties);
}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-22 15:32:56
UTC (rev 3326)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-22 16:26:08
UTC (rev 3327)
@@ -232,7 +232,7 @@
ERR.015.004.0010= Unknown group specified in OPTION MAKEDEP/MAKENOTDEP: {0}
ERR.015.004.0012= Group has an access pattern which has not been met: group(s) {0};
access pattern(s) {1}
ERR.015.004.0020= Error getting model for {0}
-ERR.015.004.0023= Error rewriting criteria: {0}
+ERR.015.004.0023= Error rewriting: {0}
ERR.015.004.0024= Unable to create a query plan that sends a criteria to
\"{0}\". This connection factory requires criteria set to true indicating that
a query against this model requires criteria.
ERR.015.004.0029= Could not resolve group symbol {0}
ERR.015.004.0035= The criteria {0} has elements from the root staging table and the
document nodes which is not allowed.
Modified: trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java 2011-07-22 15:32:56
UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java 2011-07-22 16:26:08
UTC (rev 3327)
@@ -33,7 +33,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.query.sql.symbol.ElementSymbol;
-@SuppressWarnings("nls")
+@SuppressWarnings({"nls", "unchecked"})
public class TestSTree {
@Test public void testRemoveAll() throws TeiidComponentException {
@@ -42,7 +42,7 @@
e1.setType(Integer.class);
ElementSymbol e2 = new ElementSymbol("y");
e2.setType(String.class);
- List elements = Arrays.asList(e1, e2);
+ List<ElementSymbol> elements = Arrays.asList(e1, e2);
STree map = bm.createSTree(elements, "1", 1);
for (int i = 20000; i > 0; i--) {
@@ -83,7 +83,7 @@
ElementSymbol e1 = new ElementSymbol("x");
e1.setType(Integer.class);
- List elements = Arrays.asList(e1);
+ List<ElementSymbol> elements = Arrays.asList(e1);
STree map = bm.createSTree(elements, "1", 1);
int size = (1<<16)+(1<<4)+1;
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -22,35 +22,25 @@
package org.teiid.dqp.internal.datamgr;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import junit.framework.Assert;
-
import org.teiid.language.Command;
-import org.teiid.language.QueryExpression;
import org.teiid.metadata.RuntimeMetadata;
-import org.teiid.translator.TranslatorException;
import org.teiid.translator.DataNotAvailableException;
import org.teiid.translator.Execution;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.TranslatorException;
import org.teiid.translator.UpdateExecution;
-public class FakeConnector extends ExecutionFactory {
- private static final int RESULT_SIZE = 5;
-
- private boolean executeBlocks;
- private boolean nextBatchBlocks;
- private boolean returnsFinalBatch;
- private boolean driverThrowsExceptionOnCancel;
- private long simulatedBatchRetrievalTime = 1000L;
- private ClassLoader classloader;
+public class FakeConnector extends ExecutionFactory<Object, Object> {
private int connectionCount;
private int executionCount;
-
+
public int getConnectionCount() {
return connectionCount;
}
@@ -62,123 +52,52 @@
@Override
public Execution createExecution(Command command, ExecutionContext executionContext,
RuntimeMetadata metadata, Object connection) throws TranslatorException {
executionCount++;
- return new FakeBlockingExecution(executionContext);
+ return new FakeExecution(executionContext);
}
- public Object getConnection() {
- return new FakeConnection();
- }
-
@Override
public Object getConnection(Object factory) throws TranslatorException {
+ connectionCount++;
return factory;
}
@Override
public void closeConnection(Object connection, Object factory) {
}
-
- private class FakeConnection {
- public FakeConnection() {
- connectionCount++;
- }
-
- public boolean released = false;
- public void close() {
- Assert.assertFalse("The connection should not be released more than
once", released); //$NON-NLS-1$
- released = true;
- }
- }
- private final class FakeBlockingExecution implements ResultSetExecution,
UpdateExecution {
- private boolean closed = false;
- private boolean cancelled = false;
+ public final class FakeExecution implements ResultSetExecution, UpdateExecution {
private int rowCount;
ExecutionContext ec;
- public FakeBlockingExecution(ExecutionContext ec) {
+
+ public FakeExecution(ExecutionContext ec) {
this.ec = ec;
}
- public void execute(QueryExpression query, int maxBatchSize) throws
TranslatorException {
- if (executeBlocks) {
- waitForCancel();
- }
- if (classloader != null) {
- Assert.assertSame(classloader,
Thread.currentThread().getContextClassLoader());
- }
- }
- public synchronized void cancel() throws TranslatorException {
- cancelled = true;
- this.notify();
- }
- public void close() {
- Assert.assertFalse("The execution should not be closed more than
once", closed); //$NON-NLS-1$
- closed = true;
- }
@Override
public void execute() throws TranslatorException {
ec.addWarning(new Exception("Some warning")); //$NON-NLS-1$
}
@Override
- public List next() throws TranslatorException, DataNotAvailableException {
- if (nextBatchBlocks) {
- waitForCancel();
- }
- if (this.rowCount >= RESULT_SIZE || returnsFinalBatch) {
+ public List<?> next() throws TranslatorException, DataNotAvailableException
{
+ if (this.rowCount == 1) {
return null;
}
this.rowCount++;
- return Arrays.asList(this.rowCount - 1);
+ return new ArrayList<Object>(Arrays.asList(this.rowCount - 1));
}
- private synchronized void waitForCancel() throws TranslatorException {
- try {
- this.wait(simulatedBatchRetrievalTime);
- if (cancelled && driverThrowsExceptionOnCancel) {
- throw new TranslatorException("Request cancelled");
//$NON-NLS-1$
- }
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
@Override
public int[] getUpdateCounts() throws DataNotAvailableException,
TranslatorException {
return new int[] {1};
}
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public void cancel() throws TranslatorException {
+ }
}
- public boolean isExecuteBlocks() {
- return executeBlocks;
- }
- public void setExecuteBlocks(boolean executeBlocks) {
- this.executeBlocks = executeBlocks;
- }
- public boolean isNextBatchBlocks() {
- return nextBatchBlocks;
- }
- public void setNextBatchBlocks(boolean nextBatchBlocks) {
- this.nextBatchBlocks = nextBatchBlocks;
- }
- public boolean isReturnsFinalBatch() {
- return returnsFinalBatch;
- }
- public void setReturnsFinalBatch(boolean returnsFinalBatch) {
- this.returnsFinalBatch = returnsFinalBatch;
- }
- public boolean isDriverThrowsExceptionOnCancel() {
- return driverThrowsExceptionOnCancel;
- }
- public void setDriverThrowsExceptionOnCancel(
- boolean driverThrowsExceptionOnCancel) {
- this.driverThrowsExceptionOnCancel = driverThrowsExceptionOnCancel;
- }
- public long getSimulatedBatchRetrievalTime() {
- return simulatedBatchRetrievalTime;
- }
- public void setSimulatedBatchRetrievalTime(long simulatedBatchRetrievalTime) {
- this.simulatedBatchRetrievalTime = simulatedBatchRetrievalTime;
- }
- public void setClassloader(ClassLoader classloader) {
- this.classloader = classloader;
- }
}
Modified:
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -50,7 +50,7 @@
return c;
}
protected Object getConnectionFactory(){
- return c.getConnection();
+ return c;
}
};
cm.start();
Modified:
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -87,7 +87,7 @@
int total_columns = 3;
StoredProcedure command = (StoredProcedure)helpGetCommand("{call
pm2.spTest8(?)}", EXAMPLE_BQT); //$NON-NLS-1$
command.getInputParameters().get(0).setExpression(new Constant(1));
- Call proc = (Call)new LanguageBridgeFactory(EXAMPLE_BQT).translate(command);
+ Call proc = new LanguageBridgeFactory(EXAMPLE_BQT).translate(command);
ProcedureBatchHandler pbh = new ProcedureBatchHandler(proc, exec);
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -72,7 +72,7 @@
public void testGetName() throws Exception {
Object metadataID =
TstLanguageBridgeFactory.metadata.getElementID("pm1.g1.e1"); //$NON-NLS-1$
- assertEquals("pm1.g1.e1", example("pm1.g1", "e1",
metadataID).getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ assertEquals("e1", example("pm1.g1", "e1",
metadataID).getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void testGetGroup() throws Exception {
Modified:
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -25,20 +25,10 @@
import static org.junit.Assert.*;
import org.junit.Test;
-import org.teiid.dqp.internal.process.AbstractWorkItem.ThreadState;
public class TestWorkItemState {
- private final class WorkItemRunner implements Runnable {
- TestWorkItem workItem;
-
- @Override
- public void run() {
- workItem.run();
- }
- }
-
private class TestWorkItem extends AbstractWorkItem {
private boolean isDone;
@@ -50,11 +40,6 @@
}
private TestWorkItem(boolean done, boolean callMoreWork) {
- this(done, callMoreWork, null);
- }
-
- private TestWorkItem(boolean done, boolean callMoreWork, Thread callingThread) {
- super(callingThread);
this.isDone = done;
this.callMoreWork = callMoreWork;
}
@@ -167,26 +152,4 @@
}
}
- @Test public void testUsingCallingThreadIdle() throws Exception {
- WorkItemRunner r = new WorkItemRunner();
- Thread t = new Thread(r);
- final TestWorkItem item = new TestWorkItem(false, false, t) {
- @Override
- protected boolean shouldPause() {
- return true;
- }
- };
- r.workItem = item;
- t.start();
- for (int i = 0; i < 10 && item.getThreadState() != ThreadState.IDLE; i++) {
- Thread.sleep(100);
- }
- if (item.getThreadState() != ThreadState.IDLE) {
- fail();
- }
- item.moreWork();
- //if we don't return from this call, that means that this thread has been hijacked
-
- //we should instead use t.
- }
-
}
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -1000,9 +1000,10 @@
}
@Test public void testTimestampDiffTimeStamp_Day_1() throws Exception {
+ // Moving to June, March fails because of DST
helpTestTimestampDiff(NonReserved.SQL_TSI_DAY,
- TimestampUtil.createTimestamp((2004-1900), 2, 1, 0, 0, 0,
0),
- TimestampUtil.createTimestamp((2004-1900), 3, 1, 0, 0, 0,
0),
+ TimestampUtil.createTimestamp((2004-1900), 4, 1, 0, 0, 0,
0),
+ TimestampUtil.createTimestamp((2004-1900), 5, 1, 0, 0, 0,
0),
new Long(31));
}
Property changes on:
trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java
___________________________________________________________________
Added: svn:mergeinfo
+
/branches/7.4.x/engine/src/test/java/org/teiid/query/function/TestFunction.java:3281-3325
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -757,6 +757,7 @@
}
@Test public void testSubqueryRewriteToJoinDistinct() throws Exception {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
TestQueryRewriter.helpTestRewriteCommand("Select distinct e1 from pm1.g1 as
x where exists (select pm1.g1.e1 FROM pm1.g1 where e1 = x.e1)", "SELECT DISTINCT
e1 FROM pm1.g1 AS x, (SELECT pm1.g1.e1 FROM pm1.g1) AS X__1 WHERE x.e1 = X__1.e1",
RealMetadataFactory.example1Cached());
}
@@ -764,6 +765,7 @@
* Agg does not depend on cardinality
*/
@Test public void testSubqueryRewriteToJoinGroupBy() throws Exception {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
TestQueryRewriter.helpTestRewriteCommand("Select max(e1) from pm1.g1 as x
where exists (select pm1.g1.e1 FROM pm1.g1 where e1 = x.e1) group by e2",
"SELECT MAX(e1) FROM pm1.g1 AS x, (SELECT pm1.g1.e1 FROM pm1.g1) AS X__1 WHERE x.e1 =
X__1.e1 GROUP BY e2", RealMetadataFactory.example1Cached());
}
@@ -775,6 +777,7 @@
}
@Test public void testSubqueryRewriteToJoin() throws Exception {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
TestQueryRewriter.helpTestRewriteCommand("Select e1 from pm3.g1 where exists
(select pm1.g1.e1 FROM pm1.g1 where e1 = pm3.g1.e1)", "SELECT e1 FROM pm3.g1,
(SELECT pm1.g1.e1 FROM pm1.g1) AS X__1 WHERE pm3.g1.e1 = X__1.e1",
RealMetadataFactory.example4());
}
@@ -919,6 +922,7 @@
* Same as above, but the source is much larger, so a semi-join is favorable
*/
@Test public void testSemiJoinExistsCosting() {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
ProcessorPlan plan = helpPlan("Select e1 from pm2.g2 as o where not exists
(select 1 from pm3.g1 where e1 = o.e1 having o.e2 = count(e2))",
RealMetadataFactory.example4(), //$NON-NLS-1$
new String[] { "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm2.g2 AS g_0
ORDER BY c_0, c_1" }); //$NON-NLS-1$
checkNodeTypes(plan, new int[] {
Property changes on:
trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
___________________________________________________________________
Modified: svn:mergeinfo
-
/branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java:3149-3217
+
/branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java:3149-3217,3281-3325
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -202,8 +202,8 @@
String sql = "select * from xmltable('/a/b' passing
convert('<a><b>first</b><b
x=\"1\">second</b></a>', xml) columns val xml path
'.') as x"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList("<b>first</b>"),
- Arrays.asList("<b x=\"1\">second</b>"),
+ Arrays.asList("<b xmlns=\"\">first</b>"),
+ Arrays.asList("<b xmlns=\"\"
x=\"1\">second</b>"),
};
process(sql, expected);
@@ -286,7 +286,7 @@
String sql = "select xmlquery('/a/b' passing xmlparse(document
'<a><b x=''1''/><b
x=''2''/></a>') null on empty)"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList("<b x=\"1\"/><b
x=\"2\"/>")
+ Arrays.asList("<b xmlns=\"\" x=\"1\"/><b
xmlns=\"\" x=\"2\"/>")
};
process(sql, expected);
Property changes on:
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
___________________________________________________________________
Modified: svn:mergeinfo
-
/branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java:3149-3217,3220-3275
+
/branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java:3149-3217,3220-3275,3281-3325
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -124,11 +124,11 @@
}
private Map<ElementSymbol, Integer> elements;
- private List<List> tuples;
+ private List<List<? extends Object>> tuples;
@Before public void setUp() {
elements = null;
- tuples = new ArrayList<List>();
+ tuples = new ArrayList<List<? extends Object>>();
}
private Criteria helpTestRewriteCriteria(String original, Criteria expectedCrit,
QueryMetadataInterface metadata) {
@@ -138,7 +138,7 @@
// rewrite
try {
ArrayList<Boolean> booleanVals = new
ArrayList<Boolean>(tuples.size());
- for (List<Object> tuple : tuples) {
+ for (List<?> tuple : tuples) {
booleanVals.add(new Evaluator(elements, null, null).evaluate(origCrit,
tuple));
}
actual = QueryRewriter.rewriteCriteria(origCrit, null, null, metadata);
@@ -2085,10 +2085,6 @@
helpTestRewriteCriteria("concat2('a', pm1.g1.e1) =
'xyz'", "concat('a', ifnull(pm1.g1.e1, '')) =
'xyz'"); //$NON-NLS-1$ //$NON-NLS-2$
}
- @Test public void testRewiteEvaluatableAggregate() {
- helpTestRewriteCommand("select max(1) from pm1.g1", "SELECT MAX(1)
FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
@Test public void testRewriteFromUnixTime() throws Exception {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00"));
//$NON-NLS-1$
try {
@@ -2448,5 +2444,21 @@
String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);
}
+
+ @Test public void testRewriteNestedConvert() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as integer) as long)",
"cast(pm1.g1.e3 as long)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$
//$NON-NLS-2$
+ }
+
+ @Test public void testRewriteNestedConvert1() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as integer) as string)",
"convert(convert(pm1.g1.e3, integer), string)",
RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ @Test public void testRewriteNestedConvert2() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as string) as clob)",
"convert(convert(pm1.g1.e3, string), clob)",
RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Test public void testRewriteConstantAgg() throws Exception {
+ helpTestRewriteCommand("select max(1) from pm1.g1 group by e1",
"SELECT 1 FROM pm1.g1 GROUP BY e1");
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -419,6 +419,14 @@
new String[] {"COUNT(DISTINCT ObjectValue)"},
RealMetadataFactory.exampleBQTCached() ); //$NON-NLS-1$
}
+ /**
+ * previously failed on stringkey, which is not entirely correct
+ */
+ @Test public void testInvalidAggregate10() {
+ helpValidate("SELECT xmlparse(document stringkey) FROM BQT1.SmallA GROUP BY
xmlparse(document stringkey)", //$NON-NLS-1$
+ new String[] {"XMLPARSE(DOCUMENT stringkey)"},
RealMetadataFactory.exampleBQTCached() ); //$NON-NLS-1$
+ }
+
@Test public void testInvalidAggregateIssue190644() {
helpValidate("SELECT e3 + 1 from pm1.g1 GROUP BY e2 + 1 HAVING e2 + 1 =
5", new String[] {"e3"}, RealMetadataFactory.example1Cached());
//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -436,6 +444,11 @@
"FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000
+' else '0-999' end", //$NON-NLS-1$
new String[] {}, RealMetadataFactory.exampleBQTCached());
}
+
+ @Test public void testValidAggregate4() {
+ helpValidate("SELECT max(e1), e2 is null from pm1.g1 GROUP BY e2 is
null", new String[] {}, RealMetadataFactory.example1Cached()); //$NON-NLS-1$
+ }
+
@Test public void testInvalidHaving1() {
helpValidate("SELECT e3 FROM test.group HAVING e3 > 0", new String[]
{"e3"}, exampleMetadata()); //$NON-NLS-1$ //$NON-NLS-2$
}
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/pom.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -439,16 +439,10 @@
</dependency>
<dependency>
<groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
- <version>9.1.0.8</version>
+ <artifactId>saxonhe</artifactId>
+ <version>9.2.1.5</version>
</dependency>
<dependency>
- <groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
- <classifier>dom</classifier>
- <version>9.1.0.8</version>
- </dependency>
- <dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.1.Final</version>
@@ -493,4 +487,4 @@
<
url>https://repository.jboss.org/nexus/content/repositories/snapshots/...
</snapshotRepository>
</distributionManagement>
-</project>
\ No newline at end of file
+</project>
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-07-22 15:32:56
UTC (rev 3326)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-07-22 16:26:08
UTC (rev 3327)
@@ -21,13 +21,14 @@
*/
package org.teiid.odbc;
+import java.io.IOException;
import java.sql.ParameterMetaData;
-import java.sql.ResultSetMetaData;
-import java.sql.Statement;
+import java.util.List;
import java.util.Properties;
import org.teiid.client.util.ResultsFuture;
import org.teiid.jdbc.ResultSetImpl;
+import org.teiid.odbc.PGUtil.PgColInfo;
public interface ODBCClientRemote {
@@ -62,11 +63,19 @@
// RowDescription (B)
// NoData (B)
- void sendResultSetDescription(ResultSetMetaData metaData, Statement stmt);
+ void sendResultSetDescription(List<PgColInfo> cols);
// DataRow (B)
// CommandComplete (B)
- void sendResults(String sql, ResultSetImpl rs, ResultsFuture<Void> result, boolean
describeRows);
+ void sendResults(String sql, ResultSetImpl rs, List<PgColInfo> cols,
ResultsFuture<Integer> result, boolean describeRows);
+
+ void sendCursorResults(ResultSetImpl rs, List<PgColInfo> cols,
ResultsFuture<Integer> result, int rowCount);
+
+ void sendPortalResults(String sql, ResultSetImpl rs, List<PgColInfo> cols,
ResultsFuture<Integer> result, int rowCount, boolean portal);
+
+ void sendMoveCursor(ResultSetImpl rs, int rowCount, ResultsFuture<Integer>
results);
+
+ void sendCommandComplete(String sql, int updateCount) throws IOException;
// CommandComplete (B)
void sendUpdateCount(String sql, int updateCount);
@@ -106,8 +115,5 @@
// NoticeResponse (B)
// NotificationResponse (B)
- // PortalSuspended (B)
-
-
-
+ void sendPortalSuspended();
}
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -21,14 +21,19 @@
*/
package org.teiid.odbc;
+import static org.teiid.odbc.PGUtil.convertType;
+
import java.io.IOException;
import java.io.StringReader;
import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
@@ -40,10 +45,12 @@
import org.teiid.core.util.StringUtil;
import org.teiid.jdbc.ConnectionImpl;
import org.teiid.jdbc.PreparedStatementImpl;
+import org.teiid.jdbc.ResultSetImpl;
import org.teiid.jdbc.StatementImpl;
import org.teiid.jdbc.TeiidDriver;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
+import org.teiid.odbc.PGUtil.PgColInfo;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.transport.ODBCClientInstance;
@@ -133,11 +140,17 @@
private static Pattern preparedAutoIncrement = Pattern.compile("select 1 \\s*from
pg_catalog.pg_attrdef \\s*where adrelid = \\$1 AND adnum = \\$2 " + //$NON-NLS-1$
"\\s*and pg_catalog.pg_get_expr\\(adbin, adrelid\\) \\s*like
'%nextval\\(%'", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
- private static Pattern deallocatePattern = Pattern.compile("DEALLOCATE
\"(\\w+\\d+_*)\""); //$NON-NLS-1$
- private static Pattern releasePattern = Pattern.compile("RELEASE
(\\w+\\d+_*)"); //$NON-NLS-1$
- private static Pattern savepointPattern = Pattern.compile("SAVEPOINT
(\\w+\\d+_*)"); //$NON-NLS-1$
- private static Pattern rollbackPattern =
Pattern.compile("ROLLBACK\\s*(to)*\\s*(\\w+\\d+_*)*"); //$NON-NLS-1$
+ private static Pattern cursorSelectPattern = Pattern.compile("DECLARE
\"(\\w+)\" CURSOR(\\s(WITH HOLD|SCROLL))? FOR (.*)",
Pattern.CASE_INSENSITIVE|Pattern.DOTALL); //$NON-NLS-1$
+ private static Pattern fetchPattern = Pattern.compile("FETCH (\\d+) IN
\"(\\w+)\".*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern movePattern = Pattern.compile("MOVE (\\d+) IN
\"(\\w+)\".*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern closePattern = Pattern.compile("CLOSE
\"(\\w+)\"", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern deallocatePattern = Pattern.compile("DEALLOCATE
\"(\\w+\\d+_*)\"", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern releasePattern = Pattern.compile("RELEASE
(\\w+\\d?_*)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern savepointPattern = Pattern.compile("SAVEPOINT
(\\w+\\d?_*)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern rollbackPattern =
Pattern.compile("ROLLBACK\\s*(to)*\\s*(\\w+\\d+_*)*", Pattern.CASE_INSENSITIVE);
//$NON-NLS-1$
+
+
private TeiidDriver driver;
private ODBCClientRemote client;
private Properties props;
@@ -151,6 +164,7 @@
// TODO: this is unbounded map; need to define some boundaries as to how many stmts each
session can have
private Map<String, Prepared> preparedMap = Collections.synchronizedMap(new
HashMap<String, Prepared>());
private Map<String, Portal> portalMap = Collections.synchronizedMap(new
HashMap<String, Portal>());
+ private Map<String, Cursor> cursorMap = Collections.synchronizedMap(new
HashMap<String, Cursor>());
public ODBCServerRemoteImpl(ODBCClientInstance client, AuthenticationType authType,
TeiidDriver driver) {
this.driver = driver;
@@ -196,6 +210,173 @@
}
}
+ private void cursorExecute(final String cursorName, final String sql, final
ResultsFuture<Integer> completion) {
+ if (this.connection != null) {
+ if (sql != null) {
+ try {
+ // close if the name is already used or the unnamed prepare; otherwise
+ // stmt is alive until session ends.
+ Prepared previous = this.preparedMap.remove(cursorName);
+ if (previous != null) {
+ previous.stmt.close();
+ }
+
+ final PreparedStatementImpl stmt = this.connection.prepareStatement(sql);
+ this.executionFuture = stmt.submitExecute();
+ this.executionFuture.addCompletionListener(new
ResultsFuture.CompletionListener<Boolean>() {
+ @Override
+ public void onCompletion(ResultsFuture<Boolean> future) {
+ executionFuture = null;
+ try {
+ if (future.get()) {
+ List<PgColInfo> cols =
getPgColInfo(stmt.getResultSet().getMetaData());
+ cursorMap.put(cursorName, new Cursor(cursorName, sql, stmt,
null, stmt.getResultSet(), cols));
+ client.sendCommandComplete("DECLARE CURSOR", 0); //$NON-NLS-1$
+ }
+ else {
+
errorOccurred(RuntimePlugin.Util.getString("execution_failed")); //$NON-NLS-1$
+ }
+ } catch (Throwable e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ });
+ } catch (SQLException e) {
+ errorOccurred(e);
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("no_active_connection"));
//$NON-NLS-1$
+ completion.getResultsReceiver().receiveResults(1);
+ }
+
+ }
+
+ private void cursorFetch(String cursorName, int rows, final ResultsFuture<Integer>
completion) {
+ Cursor cursor = this.cursorMap.get(cursorName);
+ if (cursor != null) {
+ cursor.fetchSize = rows;
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ this.client.sendCursorResults(cursor.rs, cursor.columnMetadata, result, rows);
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ int rowsSent = 0;
+ try {
+ rowsSent = future.get();
+ client.sendCommandComplete("FETCH", rowsSent); //$NON-NLS-1$
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(rowsSent);
+ };
+ });
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("not_bound", cursorName));
//$NON-NLS-1$
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+
+ private void cursorMove(String prepareName, int rows, final ResultsFuture<Integer>
completion) {
+
+ // win odbc driver sending a move after close; and error is ending up in failure; since
the below
+ // is not harmful it is ok to send empty move.
+ if (rows == 0) {
+ try {
+ client.sendCommandComplete("MOVE", 0); //$NON-NLS-1$
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(0);
+ return;
+ }
+
+ Cursor cursor = this.cursorMap.get(prepareName);
+ if (cursor != null) {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ this.client.sendMoveCursor(cursor.rs, rows, result);
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ int rowsMoved = 0;
+ try {
+ rowsMoved = future.get();
+ client.sendCommandComplete("MOVE", rowsMoved); //$NON-NLS-1$
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(rowsMoved);
+ };
+ });
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("not_bound", prepareName));
//$NON-NLS-1$
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+
+ private void cursorClose(String prepareName) throws SQLException, IOException {
+ Cursor cursor = this.cursorMap.remove(prepareName);
+ if (cursor != null) {
+ cursor.rs.close();
+ cursor.stmt.close();
+ this.client.sendCommandComplete("CLOSE CURSOR", 0); //$NON-NLS-1$
+ }
+ }
+
+ private void sqlExecute(final String sql, final ResultsFuture<Integer>
completion) throws SQLException {
+ String modfiedSQL = fixSQL(sql);
+ final StatementImpl stmt = connection.createStatement();
+ executionFuture = stmt.submitExecute(modfiedSQL);
+ executionFuture.addCompletionListener(new
ResultsFuture.CompletionListener<Boolean>() {
+ @Override
+ public void onCompletion(ResultsFuture<Boolean> future) {
+ executionFuture = null;
+ try {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ if (future.get()) {
+ if (stmt.getResultSet() != null) {
+ List<PgColInfo> cols =
getPgColInfo(stmt.getResultSet().getMetaData());
+ client.sendResults(sql, stmt.getResultSet(), cols, result,
true);
+ }
+ else {
+ // handles the "SET" commands.
+ client.sendUpdateCount(sql, 0);
+ result.getResultsReceiver().receiveResults(1);
+ }
+ } else {
+ client.sendUpdateCount(sql, stmt.getUpdateCount());
+ setEncoding();
+ result.getResultsReceiver().receiveResults(1);
+ }
+ result.addCompletionListener(new
ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ LogManager.logDetail(LogConstants.CTX_ODBC, e, "Error closing
statement"); //$NON-NLS-1$
+ }
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ });
+ } catch (Throwable e) {
+ errorOccurred(e);
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+ });
+ }
+
@Override
public void prepare(String prepareName, String sql, int[] paramType) {
if (this.connection != null) {
@@ -274,60 +455,96 @@
bindName = UNNAMED;
}
+ // special case cursor execution through portal
+ final Cursor cursor = this.cursorMap.get(bindName);
+ if (cursor != null) {
+ sendCursorResults(cursor);
+ return;
+ }
+
final Portal query = this.portalMap.get(bindName);
if (query == null) {
errorOccurred(RuntimePlugin.Util.getString("not_bound", bindName));
//$NON-NLS-1$
- }
- else {
- if (query.sql.trim().isEmpty()) {
- this.client.emptyQueryReceived();
- return;
- }
-
- final PreparedStatementImpl stmt = query.stmt;
- try {
- // maxRows = 0, means unlimited.
- if (maxRows != 0) {
- stmt.setMaxRows(maxRows);
- }
-
- this.executionFuture = stmt.submitExecute();
- executionFuture.addCompletionListener(new
ResultsFuture.CompletionListener<Boolean>() {
- @Override
- public void onCompletion(ResultsFuture<Boolean> future) {
- executionFuture = null;
- try {
- ResultsFuture<Void> result = null;
- if (future.get()) {
- result = new ResultsFuture<Void>();
- client.sendResults(query.sql, stmt.getResultSet(), result,
true);
- } else {
- result = ResultsFuture.NULL_FUTURE;
- client.sendUpdateCount(query.sql, stmt.getUpdateCount());
- setEncoding();
- }
- result.addCompletionListener(new
ResultsFuture.CompletionListener<Void>() {
- public void onCompletion(ResultsFuture<Void> future)
{
- try {
- future.get();
- doneExecuting();
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- } catch (ExecutionException e) {
- errorOccurred(e.getCause());
- }
- };
- });
- } catch (Throwable e) {
- errorOccurred(e);
- }
- }
- });
- } catch (SQLException e) {
- errorOccurred(e);
- }
+ return;
+ }
+
+ if (query.sql.trim().isEmpty()) {
+ this.client.emptyQueryReceived();
+ return;
}
+
+ sendPortalResults(maxRows, query);
}
+
+ private void sendPortalResults(int maxRows, final Portal query) {
+ final PreparedStatementImpl stmt = query.stmt;
+ try {
+ // maxRows = 0, means unlimited.
+ if (maxRows != 0) {
+ stmt.setMaxRows(maxRows);
+ }
+
+ this.executionFuture = stmt.submitExecute();
+ executionFuture.addCompletionListener(new
ResultsFuture.CompletionListener<Boolean>() {
+ @Override
+ public void onCompletion(ResultsFuture<Boolean> future) {
+ executionFuture = null;
+ try {
+ ResultsFuture<Integer> result = new
ResultsFuture<Integer>();
+ if (future.get()) {
+ List<PgColInfo> cols =
getPgColInfo(stmt.getResultSet().getMetaData());
+ client.sendResults(query.sql, stmt.getResultSet(), cols,
result, true);
+ } else {
+ // null future
+ client.sendUpdateCount(query.sql, stmt.getUpdateCount());
+ setEncoding();
+ result.getResultsReceiver().receiveResults(1);
+ }
+ result.addCompletionListener(new
ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ future.get();
+ doneExecuting();
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ }
+ };
+ });
+ } catch (Throwable e) {
+ errorOccurred(e);
+ }
+ }
+ });
+ } catch (SQLException e) {
+ errorOccurred(e);
+ }
+ }
+
+ private void sendCursorResults(final Cursor cursor) {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ this.client.sendPortalResults(cursor.sql, cursor.rs, cursor.columnMetadata, result,
cursor.fetchSize, true);
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ int rowsSent = future.get();
+ if (rowsSent < cursor.fetchSize) {
+ client.sendCommandComplete(cursor.sql, 0);
+ }
+ else {
+ client.sendPortalSuspended();
+ }
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ };
+ });
+ }
private String fixSQL(String sql) {
String modified = modifySQL(sql);
@@ -409,16 +626,6 @@
}
else if ((m = rollbackPattern.matcher(modified)).matches()) {
return "ROLLBACK"; //$NON-NLS-1$
- }
- else if ((m = savepointPattern.matcher(modified)).matches()) {
- return "SELECT 'SAVEPOINT'"; //$NON-NLS-1$
- }
- else if ((m = releasePattern.matcher(modified)).matches()) {
- return "SELECT 'RELEASE'"; //$NON-NLS-1$
- }
- else if ((m = deallocatePattern.matcher(modified)).matches()) {
- closePreparedStatement(m.group(1));
- return "SELECT 'DEALLOCATE'"; //$NON-NLS-1$
}
}
modified = sql;
@@ -431,7 +638,7 @@
@Override
public void executeQuery(final String query) {
if (beginExecution()) {
- this.client.errorOccurred("Awaiting asynch result"); //$NON-NLS-1$
+ errorOccurred("Awaiting asynch result"); //$NON-NLS-1$
ready();
return;
}
@@ -482,7 +689,8 @@
// followed by a RowDescription message describing the rows that will be returned
when the statement
// is eventually executed (or a NoData message if the statement will not return
rows).
- this.client.sendResultSetDescription(query.stmt.getMetaData(), query.stmt);
+ List<PgColInfo> cols = getPgColInfo(query.stmt.getMetaData());
+ this.client.sendResultSetDescription(cols);
} catch (SQLException e) {
errorOccurred(e);
}
@@ -516,7 +724,8 @@
}
else {
try {
- this.client.sendResultSetDescription(query.stmt.getMetaData(), query.stmt);
+ List<PgColInfo> cols = getPgColInfo(query.stmt.getMetaData());
+ this.client.sendResultSetDescription(cols);
} catch (SQLException e) {
errorOccurred(e);
}
@@ -622,6 +831,9 @@
try {
if (this.connection != null) {
+ if (!this.connection.getAutoCommit()) {
+ this.connection.rollback(false);
+ }
this.connection.close();
}
} catch (SQLException e) {
@@ -663,90 +875,124 @@
private final class QueryWorkItem implements Runnable {
private final ScriptReader reader;
- String modfiedSQL;
String sql;
private QueryWorkItem(String query) {
- this.reader = new ScriptReader(new StringReader(query));
+ this.reader = new ScriptReader(new StringReader(query));
}
@Override
public void run() {
try {
- if (modfiedSQL == null) {
+ if (sql == null) {
sql = reader.readStatement();
- modfiedSQL = fixSQL(sql);
}
- while (modfiedSQL != null) {
+ while (sql != null) {
try {
- final StatementImpl stmt = connection.createStatement();
- executionFuture = stmt.submitExecute(modfiedSQL);
- executionFuture.addCompletionListener(new
ResultsFuture.CompletionListener<Boolean>() {
- @Override
- public void onCompletion(ResultsFuture<Boolean> future) {
- executionFuture = null;
- try {
- ResultsFuture<Void> result = null;
- if (future.get()) {
- if (stmt.getResultSet() != null) {
- result = new ResultsFuture<Void>();
- client.sendResults(sql, stmt.getResultSet(), result,
true);
- }
- else {
- // handles the "SET" commands.
- result = ResultsFuture.NULL_FUTURE;
- client.sendUpdateCount(sql, 0);
- }
- } else {
- result = ResultsFuture.NULL_FUTURE;
- client.sendUpdateCount(sql, stmt.getUpdateCount());
- setEncoding();
- }
- result.addCompletionListener(new
ResultsFuture.CompletionListener<Void>() {
- public void onCompletion(ResultsFuture<Void> future)
{
- try {
- future.get();
- sql = reader.readStatement();
- modfiedSQL = fixSQL(sql);
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- } catch (IOException e) {
- client.errorOccurred(e);
- return;
- } catch (ExecutionException e) {
- client.errorOccurred(e.getCause());
- return;
- } finally {
- try {
- stmt.close();
- } catch (SQLException e) {
- LogManager.logDetail(LogConstants.CTX_ODBC, e, "Error closing
statement"); //$NON-NLS-1$
- }
- }
- QueryWorkItem.this.run(); //continue processing
- };
- });
- } catch (Throwable e) {
- client.errorOccurred(e);
- return;
- }
- }
- });
+
+ ResultsFuture<Integer> results = new
ResultsFuture<Integer>();
+ results.addCompletionListener(new
ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ future.get();
+ sql = reader.readStatement();
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (IOException e) {
+ client.errorOccurred(e);
+ return;
+ } catch (ExecutionException e) {
+ client.errorOccurred(e.getCause());
+ return;
+ }
+ QueryWorkItem.this.run(); //continue processing
+ };
+ });
+
+ if (isErrorOccurred()) {
+ if (!connection.getAutoCommit()) {
+ connection.rollback(false);
+ }
+ break;
+ }
+
+ Matcher m = null;
+ if ((m = cursorSelectPattern.matcher(sql)).matches()){
+ cursorExecute(m.group(1), fixSQL(m.group(4)), results);
+ }
+ else if ((m = fetchPattern.matcher(sql)).matches()){
+ cursorFetch(m.group(2), Integer.parseInt(m.group(1)), results);
+ }
+ else if ((m = movePattern.matcher(sql)).matches()){
+ cursorMove(m.group(2), Integer.parseInt(m.group(1)), results);
+ }
+ else if ((m = closePattern.matcher(sql)).matches()){
+ cursorClose(m.group(1));
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else if ((m = savepointPattern.matcher(sql)).matches()) {
+ client.sendCommandComplete("SAVEPOINT", 0); //$NON-NLS-1$
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else if ((m = releasePattern.matcher(sql)).matches()) {
+ client.sendCommandComplete("RELEASE", 0); //$NON-NLS-1$
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else if ((m = deallocatePattern.matcher(sql)).matches()) {
+ closePreparedStatement(m.group(1));
+ client.sendCommandComplete("DEALLOCATE", 0); //$NON-NLS-1$
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else {
+ sqlExecute(sql, results);
+ }
return; //wait for the execution to finish
} catch (SQLException e) {
- client.errorOccurred(e);
+ errorOccurred(e);
break;
}
}
} catch(IOException e) {
- client.errorOccurred(e);
+ errorOccurred(e);
}
doneExecuting();
ready();
}
-
}
-
+
+ private List<PgColInfo> getPgColInfo(ResultSetMetaData meta)
+ throws SQLException {
+ int columns = meta.getColumnCount();
+ final ArrayList<PgColInfo> result = new ArrayList<PgColInfo>(columns);
+ for (int i = 1; i < columns + 1; i++) {
+ final PgColInfo info = new PgColInfo();
+ info.name = meta.getColumnLabel(i).toLowerCase();
+ info.type = meta.getColumnType(i);
+ info.type = convertType(info.type);
+ info.precision = meta.getColumnDisplaySize(i);
+ String name = meta.getColumnName(i);
+ String table = meta.getTableName(i);
+ String schema = meta.getSchemaName(i);
+ if (schema != null) {
+ final PreparedStatementImpl ps = this.connection.prepareStatement("select
attrelid, attnum, typoid from matpg_relatt where attname = ? and relname = ? and nspname =
?"); //$NON-NLS-1$
+ ps.setString(1, name);
+ ps.setString(2, table);
+ ps.setString(3, schema);
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) {
+ info.reloid = rs.getInt(1);
+ info.attnum = rs.getShort(2);
+ int specificType = rs.getInt(3);
+ if (!rs.wasNull()) {
+ info.type = specificType;
+ }
+ }
+ }
+ result.add(info);
+ }
+ return result;
+ }
+
/**
* Represents a PostgreSQL Prepared object.
*/
@@ -777,7 +1023,7 @@
/**
* The list of parameter types (if set).
*/
- int[] paramType;
+ int[] paramType;
}
/**
@@ -813,7 +1059,22 @@
/**
* The prepared statement.
*/
- PreparedStatementImpl stmt;
+ PreparedStatementImpl stmt;
}
+
+ static class Cursor extends Prepared {
+ ResultSetImpl rs;
+ int fetchSize = 1000;
+ /**
+ * calculated column metadata
+ */
+ List<PgColInfo> columnMetadata;
+
+ public Cursor (String name, String sql, PreparedStatementImpl stmt, int[] paramType,
ResultSetImpl rs, List<PgColInfo> colMetadata) {
+ super(name, sql, stmt, paramType);
+ this.rs = rs;
+ this.columnMetadata = colMetadata;
+ }
+ }
}
Copied: trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java (from rev 3325,
branches/7.4.x/runtime/src/main/java/org/teiid/odbc/PGUtil.java)
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java (rev
0)
+++ trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java 2011-07-22 16:26:08 UTC (rev
3327)
@@ -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.odbc;
+
+import java.sql.Types;
+
+import org.teiid.deployers.PgCatalogMetadataStore;
+
+public class PGUtil {
+
+ public static final int PG_TYPE_VARCHAR = 1043;
+
+ public static final int PG_TYPE_BOOL = 16;
+ public static final int PG_TYPE_BYTEA = 17;
+ public static final int PG_TYPE_BPCHAR = 1042;
+ public static final int PG_TYPE_INT8 = 20;
+ public static final int PG_TYPE_INT2 = 21;
+ public static final int PG_TYPE_INT4 = 23;
+ public static final int PG_TYPE_TEXT = 25;
+ //private static final int PG_TYPE_OID = 26;
+ public static final int PG_TYPE_FLOAT4 = 700;
+ public static final int PG_TYPE_FLOAT8 = 701;
+ public static final int PG_TYPE_UNKNOWN = 705;
+
+ public static final int PG_TYPE_OIDVECTOR = PgCatalogMetadataStore.PG_TYPE_OIDVECTOR;
+ public static final int PG_TYPE_OIDARRAY = PgCatalogMetadataStore.PG_TYPE_OIDARRAY;
+ public static final int PG_TYPE_CHARARRAY = PgCatalogMetadataStore.PG_TYPE_CHARARRAY;
+ public static final int PG_TYPE_TEXTARRAY = PgCatalogMetadataStore.PG_TYPE_TEXTARRAY;
+
+ public static final int PG_TYPE_DATE = 1082;
+ public static final int PG_TYPE_TIME = 1083;
+ public static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
+ public static final int PG_TYPE_NUMERIC = 1700;
+ //private static final int PG_TYPE_LO = 14939;
+
+ public static class PgColInfo {
+ public String name;
+ public int reloid;
+ public short attnum;
+ public int type;
+ public int precision;
+ }
+
+ /**
+ * Types.ARRAY is not supported
+ */
+ public static int convertType(final int type) {
+ switch (type) {
+ case Types.BIT:
+ case Types.BOOLEAN:
+ return PG_TYPE_BOOL;
+ case Types.VARCHAR:
+ return PG_TYPE_VARCHAR;
+ case Types.CHAR:
+ return PG_TYPE_BPCHAR;
+ case Types.TINYINT:
+ case Types.SMALLINT:
+ return PG_TYPE_INT2;
+ case Types.INTEGER:
+ return PG_TYPE_INT4;
+ case Types.BIGINT:
+ return PG_TYPE_INT8;
+ case Types.NUMERIC:
+ case Types.DECIMAL:
+ return PG_TYPE_NUMERIC;
+ case Types.FLOAT:
+ case Types.REAL:
+ return PG_TYPE_FLOAT4;
+ case Types.DOUBLE:
+ return PG_TYPE_FLOAT8;
+ case Types.TIME:
+ return PG_TYPE_TIME;
+ case Types.DATE:
+ return PG_TYPE_DATE;
+ case Types.TIMESTAMP:
+ return PG_TYPE_TIMESTAMP_NO_TMZONE;
+
+ case Types.BLOB:
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ return PG_TYPE_BYTEA;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ return PG_TYPE_TEXT;
+
+ case Types.SQLXML:
+ return PG_TYPE_TEXT;
+
+ default:
+ return PG_TYPE_UNKNOWN;
+ }
+ }
+}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-07-22
15:32:56 UTC (rev 3326)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -21,6 +21,26 @@
* 02110-1301 USA.
*/package org.teiid.transport;
+import static org.teiid.odbc.PGUtil.PG_TYPE_BOOL;
+import static org.teiid.odbc.PGUtil.PG_TYPE_BPCHAR;
+import static org.teiid.odbc.PGUtil.PG_TYPE_BYTEA;
+import static org.teiid.odbc.PGUtil.PG_TYPE_CHARARRAY;
+import static org.teiid.odbc.PGUtil.PG_TYPE_DATE;
+import static org.teiid.odbc.PGUtil.PG_TYPE_FLOAT4;
+import static org.teiid.odbc.PGUtil.PG_TYPE_FLOAT8;
+import static org.teiid.odbc.PGUtil.PG_TYPE_INT2;
+import static org.teiid.odbc.PGUtil.PG_TYPE_INT4;
+import static org.teiid.odbc.PGUtil.PG_TYPE_INT8;
+import static org.teiid.odbc.PGUtil.PG_TYPE_NUMERIC;
+import static org.teiid.odbc.PGUtil.PG_TYPE_OIDARRAY;
+import static org.teiid.odbc.PGUtil.PG_TYPE_OIDVECTOR;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TEXT;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TEXTARRAY;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TIME;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TIMESTAMP_NO_TMZONE;
+import static org.teiid.odbc.PGUtil.PG_TYPE_UNKNOWN;
+import static org.teiid.odbc.PGUtil.PG_TYPE_VARCHAR;
+
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -32,13 +52,9 @@
import java.sql.Blob;
import java.sql.Clob;
import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
import java.sql.SQLException;
-import java.sql.Statement;
import java.sql.Types;
-import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@@ -58,16 +74,15 @@
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.ReflectionHelper;
-import org.teiid.deployers.PgCatalogMetadataStore;
import org.teiid.jdbc.ResultSetImpl;
import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.net.socket.ServiceInvocationStruct;
import org.teiid.odbc.ODBCClientRemote;
+import org.teiid.odbc.PGUtil.PgColInfo;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.transport.pg.PGbytea;
-
/**
* Represents the messages going from Server --> PG ODBC Client
* Some parts of this code is taken from H2's implementation of ODBC
@@ -92,19 +107,24 @@
}
}
}
-
+
+ // 300k
+ static int ODBC_SOCKET_BUFF_SIZE =
Integer.parseInt(System.getProperty("ODBCPacketSize", "307200"));
+
private final class ResultsWorkItem implements Runnable {
private final List<PgColInfo> cols;
- private final String sql;
private final ResultSetImpl rs;
- private final ResultsFuture<Void> result;
+ private final ResultsFuture<Integer> result;
+ private int rows2Send;
+ private int rowsSent = 0;
+ private int rowsInBuffer = 0;
+ private ChannelBuffer buffer = ChannelBuffers.directBuffer(ODBC_SOCKET_BUFF_SIZE);
- private ResultsWorkItem(List<PgColInfo> cols, String sql,
- ResultSetImpl rs, ResultsFuture<Void> result) {
+ private ResultsWorkItem(List<PgColInfo> cols, ResultSetImpl rs,
ResultsFuture<Integer> result, int rows2Send) {
this.cols = cols;
- this.sql = sql;
this.rs = rs;
this.result = result;
+ this.rows2Send = rows2Send;
}
@Override
@@ -117,8 +137,10 @@
@Override
public void onCompletion(ResultsFuture<Boolean> future) {
if (processRow(future)) {
- //this can be recursive, but ideally won't be called many times
- ResultsWorkItem.this.run();
+ if (rowsSent != rows2Send) {
+ //this can be recursive, but ideally won't be called many times
+ ResultsWorkItem.this.run();
+ }
}
}
});
@@ -138,10 +160,18 @@
boolean processNext = true;
try {
if (future.get()) {
- sendDataRow(rs, cols);
+ sendDataRow(rs, cols, buffer);
+ rowsSent++;
+ rowsInBuffer++;
+ boolean done = rowsSent == rows2Send;
+ flushResults(done);
+ processNext = !done;
+ if (done) {
+ result.getResultsReceiver().receiveResults(rowsSent);
+ }
} else {
- sendCommandComplete(sql, 0);
- result.getResultsReceiver().receiveResults(null);
+ sendContents(buffer);
+ result.getResultsReceiver().receiveResults(rowsSent);
processNext = false;
}
} catch (Throwable t) {
@@ -150,33 +180,17 @@
}
return processNext;
}
+
+ private void flushResults(boolean force) {
+ int avgRowsize = buffer.readableBytes()/rowsInBuffer;
+ if (force || buffer.writableBytes() < (avgRowsize*2)) {
+ sendContents(buffer);
+ buffer= ChannelBuffers.directBuffer(ODBC_SOCKET_BUFF_SIZE);
+ rowsInBuffer = 0;
+ }
+ }
}
-
- private static final int PG_TYPE_VARCHAR = 1043;
-
- private static final int PG_TYPE_BOOL = 16;
- private static final int PG_TYPE_BYTEA = 17;
- private static final int PG_TYPE_BPCHAR = 1042;
- private static final int PG_TYPE_INT8 = 20;
- private static final int PG_TYPE_INT2 = 21;
- private static final int PG_TYPE_INT4 = 23;
- private static final int PG_TYPE_TEXT = 25;
- //private static final int PG_TYPE_OID = 26;
- private static final int PG_TYPE_FLOAT4 = 700;
- private static final int PG_TYPE_FLOAT8 = 701;
- private static final int PG_TYPE_UNKNOWN = 705;
- private static final int PG_TYPE_OIDVECTOR =
PgCatalogMetadataStore.PG_TYPE_OIDVECTOR;
- private static final int PG_TYPE_OIDARRAY = PgCatalogMetadataStore.PG_TYPE_OIDARRAY;
- private static final int PG_TYPE_CHARARRAY =
PgCatalogMetadataStore.PG_TYPE_CHARARRAY;
- private static final int PG_TYPE_TEXTARRAY =
PgCatalogMetadataStore.PG_TYPE_TEXTARRAY;
-
- private static final int PG_TYPE_DATE = 1082;
- private static final int PG_TYPE_TIME = 1083;
- private static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
- private static final int PG_TYPE_NUMERIC = 1700;
- //private static final int PG_TYPE_LO = 14939;
-
private DataOutputStream dataOut;
private ByteArrayOutputStream outBuffer;
private char messageType;
@@ -191,7 +205,7 @@
private SSLConfiguration config;
- public PgBackendProtocol(int maxLobSize, SSLConfiguration config) {
+ public PgBackendProtocol(int maxLobSize, SSLConfiguration config) {
this.maxLobSize = maxLobSize;
this.config = config;
}
@@ -340,35 +354,65 @@
}
@Override
- public void sendResultSetDescription(ResultSetMetaData metaData, Statement stmt) {
+ public void sendResultSetDescription(List<PgColInfo> cols) {
try {
+ sendRowDescription(cols);
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void sendCursorResults(ResultSetImpl rs, List<PgColInfo> cols,
ResultsFuture<Integer> result, int rowCount) {
+ try {
+ sendRowDescription(cols);
+
+ ResultsWorkItem r = new ResultsWorkItem(cols, rs, result, rowCount);
+ r.run();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void sendPortalResults(String sql, ResultSetImpl rs, List<PgColInfo> cols,
ResultsFuture<Integer> result, int rowCount, boolean portal) {
+ ResultsWorkItem r = new ResultsWorkItem(cols, rs, result, rowCount);
+ r.run();
+ }
+
+ @Override
+ public void sendMoveCursor(ResultSetImpl rs, int rowCount, ResultsFuture<Integer>
results) {
+ try {
try {
- List<PgColInfo> cols = getPgColInfo(metaData, stmt);
- sendRowDescription(cols);
+ int rowsMoved = 0;
+ for (int i = 0; i < rowCount; i++) {
+ if (!rs.next()) {
+ break;
+ }
+ rowsMoved++;
+ }
+ results.getResultsReceiver().receiveResults(rowsMoved);
} catch (SQLException e) {
- sendErrorResponse(e);
- }
+ sendErrorResponse(e);
+ }
} catch (IOException e) {
terminate(e);
}
- }
+ }
@Override
- public void sendResults(final String sql, final ResultSetImpl rs,
ResultsFuture<Void> result, boolean describeRows) {
+ public void sendResults(final String sql, final ResultSetImpl rs, List<PgColInfo>
cols, ResultsFuture<Integer> result, boolean describeRows) {
try {
if (nextFuture != null) {
sendErrorResponse(new IllegalStateException("Pending results have not been
sent")); //$NON-NLS-1$
}
- ResultSetMetaData meta = rs.getMetaData();
- List<PgColInfo> cols = getPgColInfo(meta, rs.getStatement());
if (describeRows) {
sendRowDescription(cols);
}
- Runnable r = new ResultsWorkItem(cols, sql, rs, result);
+ ResultsWorkItem r = new ResultsWorkItem(cols, rs, result, -1);
r.run();
- } catch (SQLException e) {
- result.getResultsReceiver().exceptionOccurred(e);
+ sendCommandComplete(sql, 0);
} catch (IOException e) {
terminate(e);
}
@@ -425,8 +469,9 @@
startMessage('I');
sendMessage();
}
-
- private void sendCommandComplete(String sql, int updateCount) throws IOException {
+
+ @Override
+ public void sendCommandComplete(String sql, int updateCount) throws IOException {
startMessage('C');
sql = sql.trim().toUpperCase();
// TODO remove remarks at the beginning
@@ -439,7 +484,7 @@
tag = "UPDATE " + updateCount;
} else if (sql.startsWith("SELECT") || sql.startsWith("CALL")) {
tag = "SELECT";
- } else if (sql.startsWith("BEGIN")) {
+ } else if (sql.startsWith("BEGIN") || sql.startsWith("START
TRANSACTION")) {
tag = "BEGIN";
} else if (sql.startsWith("COMMIT")) {
tag = "COMMIT";
@@ -447,15 +492,23 @@
tag = "ROLLBACK";
} else if (sql.startsWith("SET ")) {
tag = "SET";
- }else {
- trace("Check command tag:", sql);
- tag = "UPDATE " + updateCount;
+ } else if (sql.startsWith("DECLARE CURSOR")) {
+ tag = "DECLARE CURSOR";
+ } else if (sql.startsWith("CLOSE CURSOR")) {
+ tag = "CLOSE CURSOR";
+ } else if (sql.startsWith("FETCH")) {
+ tag = "FETCH "+ updateCount;
+ } else if (sql.startsWith("MOVE")) {
+ tag = "MOVE "+ updateCount;
}
+ else {
+ tag = sql;
+ }
writeString(tag);
sendMessage();
}
- private void sendDataRow(ResultSet rs, List<PgColInfo> cols) throws SQLException,
IOException {
+ private void sendDataRow(ResultSet rs, List<PgColInfo> cols, ChannelBuffer buffer)
throws SQLException, IOException {
startMessage('D');
writeShort(cols.size());
for (int i = 0; i < cols.size(); i++) {
@@ -467,9 +520,18 @@
write(bytes);
}
}
- sendMessage();
+
+ byte[] buff = outBuffer.toByteArray();
+ int len = buff.length;
+ this.outBuffer = null;
+ this.dataOut = null;
+
+ // now build the wire contents.
+ buffer.writeByte((byte)this.messageType);
+ buffer.writeInt(len+4);
+ buffer.writeBytes(buff);
}
-
+
private byte[] getContent(ResultSet rs, PgColInfo col, int column) throws SQLException,
TeiidSQLException, IOException {
byte[] bytes = null;
switch (col.type) {
@@ -612,20 +674,7 @@
write(0);
sendMessage();
}
-
- private void sendNoData() {
- startMessage('n');
- sendMessage();
- }
- private static class PgColInfo {
- String name;
- int reloid;
- short attnum;
- int type;
- int precision;
- }
-
private void sendRowDescription(List<PgColInfo> cols) throws IOException {
startMessage('T');
writeShort(cols.size());
@@ -647,46 +696,6 @@
sendMessage();
}
- private List<PgColInfo> getPgColInfo(ResultSetMetaData meta, Statement stmt)
- throws SQLException {
- int columns = meta.getColumnCount();
- ArrayList<PgColInfo> result = new ArrayList<PgColInfo>(columns);
- for (int i = 1; i < columns + 1; i++) {
- PgColInfo info = new PgColInfo();
- info.name = meta.getColumnName(i).toLowerCase();
- info.type = meta.getColumnType(i);
- info.type = convertType(info.type);
- info.precision = meta.getColumnDisplaySize(i);
- String name = meta.getColumnName(i);
- String table = meta.getTableName(i);
- String schema = meta.getSchemaName(i);
- if (schema != null) {
- PreparedStatement ps = null;
- try {
- ps = stmt.getConnection().prepareStatement("select attrelid, attnum, typoid
from matpg_relatt where attname = ? and relname = ? and nspname = ?");
- ps.setString(1, name);
- ps.setString(2, table);
- ps.setString(3, schema);
- ResultSet rs = ps.executeQuery();
- if (rs.next()) {
- info.reloid = rs.getInt(1);
- info.attnum = rs.getShort(2);
- int specificType = rs.getInt(3);
- if (!rs.wasNull()) {
- info.type = specificType;
- }
- }
- } finally {
- if (ps != null) {
- ps.close();
- }
- }
- }
- result.add(info);
- }
- return result;
- }
-
private int getTypeSize(int pgType, int precision) {
switch (pgType) {
case PG_TYPE_VARCHAR:
@@ -728,6 +737,12 @@
startMessage('2');
sendMessage();
}
+
+ @Override
+ public void sendPortalSuspended() {
+ startMessage('s');
+ sendMessage();
+ }
private void sendAuthenticationCleartextPassword() throws IOException {
startMessage('R');
@@ -844,6 +859,10 @@
buffer.writeBytes(buff);
Channels.write(this.ctx, this.message.getFuture(), buffer,
this.message.getRemoteAddress());
}
+
+ private void sendContents(ChannelBuffer buffer) {
+ Channels.write(this.ctx, this.message.getFuture(), buffer,
this.message.getRemoteAddress());
+ }
private static void trace(String... msg) {
LogManager.logTrace(LogConstants.CTX_ODBC, (Object[])msg);
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-07-22 15:32:56
UTC (rev 3326)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-07-22 16:26:08
UTC (rev 3327)
@@ -92,5 +92,6 @@
ambigious_name=Ambiguous VDB name specified. Only single occurrence of the "."
is allowed in the VDB name. Also, when version based vdb name is specified, then a
separate "version" connection option is not allowed:{0}.{1}
lo_not_supported=LO functions are not supported
SSLConfiguration.no_anonymous=The anonymous cipher suite TLS_DH_anon_WITH_AES_128_CBC_SHA
is not available. Please change the transport to be non-SSL or use non-anonymous SSL.
+execution_failed=Cursor execution failed
PgBackendProtocol.ssl_error=Could not initialize ODBC SSL. non-SSL connections will
still be allowed.
\ No newline at end of file
Modified:
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
===================================================================
---
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -26,24 +26,39 @@
import java.lang.Thread.UncaughtExceptionHandler;
import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
-import java.util.LinkedHashMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
-import org.jboss.netty.handler.timeout.TimeoutException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.dqp.internal.datamgr.ConnectorManager;
+import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
+import org.teiid.language.Command;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.FunctionParameter;
-import org.teiid.metadata.MetadataStore;
-import org.teiid.metadata.Schema;
+import org.teiid.metadata.RuntimeMetadata;
import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.function.metadata.FunctionCategoryConstants;
-import org.teiid.query.metadata.TransformationMetadata.Resource;
+import org.teiid.translator.DataNotAvailableException;
+import org.teiid.translator.Execution;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ExecutionFactory;
+import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.TranslatorException;
@SuppressWarnings("nls")
public class TestLocalConnections {
@@ -62,12 +77,14 @@
static Condition waiting = lock.newCondition();
static Condition wait = lock.newCondition();
+ static Semaphore sourceCounter = new Semaphore(0);
+
public static int blocking() throws InterruptedException {
lock.lock();
try {
waiting.signal();
if (!wait.await(2, TimeUnit.SECONDS)) {
- throw new TimeoutException();
+ throw new RuntimeException();
}
} finally {
lock.unlock();
@@ -77,15 +94,75 @@
static FakeServer server = new FakeServer();
- @BeforeClass public static void oneTimeSetup() {
+ @SuppressWarnings("serial")
+ @BeforeClass public static void oneTimeSetup() throws Exception {
server.setUseCallingThread(true);
- MetadataStore ms = new MetadataStore();
- Schema s = new Schema();
- s.setName("test");
+ server.setConnectorManagerRepository(new ConnectorManagerRepository() {
+ @Override
+ public ConnectorManager getConnectorManager(String connectorName) {
+ return new ConnectorManager(connectorName, connectorName) {
+ @Override
+ protected ExecutionFactory<Object, Object> getExecutionFactory() {
+ return new ExecutionFactory<Object, Object>() {
+ @Override
+ public Execution createExecution(Command command,
+ ExecutionContext executionContext,
+ RuntimeMetadata metadata, Object connection)
+ throws TranslatorException {
+ return new ResultSetExecution() {
+
+ boolean returnedRow = false;
+
+ @Override
+ public void execute() throws TranslatorException {
+ lock.lock();
+ try {
+ sourceCounter.release();
+ if (!wait.await(2, TimeUnit.SECONDS)) {
+ throw new RuntimeException();
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public void cancel() throws TranslatorException {
+
+ }
+
+ @Override
+ public List<?> next() throws TranslatorException,
DataNotAvailableException {
+ if (returnedRow) {
+ return null;
+ }
+ returnedRow = true;
+ return new ArrayList<Object>(Collections.singleton(null));
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ protected Object getConnectionFactory()
+ throws TranslatorException {
+ return null;
+ }
+ };
+ }
+ });
FunctionMethod function = new FunctionMethod("foo", null,
FunctionCategoryConstants.MISCELLANEOUS, PushDown.CANNOT_PUSHDOWN,
TestLocalConnections.class.getName(), "blocking", new FunctionParameter[0], new
FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER), true,
FunctionMethod.Determinism.NONDETERMINISTIC);
- s.addFunction(function);
- ms.addSchema(s);
- server.deployVDB("test", ms, new LinkedHashMap<String,
Resource>());
+ HashMap<String, Collection<FunctionMethod>> udfs = new
HashMap<String, Collection<FunctionMethod>>();
+ udfs.put("test", Arrays.asList(function));
+ server.deployVDB("test", UnitTestUtil.getTestDataPath() +
"/PartsSupplier.vdb", udfs);
}
@AfterClass public static void oneTimeTearDown() {
@@ -102,6 +179,7 @@
Statement s = c.createStatement();
s.execute("select foo()");
+ s.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -131,9 +209,129 @@
if (t.isAlive()) {
fail();
}
+ s.close();
if (handler.t != null) {
throw handler.t;
}
}
+ @Test public void testUseInDifferentThreads() throws Throwable {
+ Connection c = server.createConnection("jdbc:teiid:test");
+
+ final Statement s = c.createStatement();
+ s.execute("select 1");
+
+ assertFalse(server.dqp.getRequests().isEmpty());
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ s.close();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+ t.start();
+ t.join(2000);
+ if (t.isAlive()) {
+ fail();
+ }
+
+ assertTrue(server.dqp.getRequests().isEmpty());
+
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
+ @Test public void testWait() throws Throwable {
+ final Connection c = server.createConnection("jdbc:teiid:test");
+
+ Thread t = new Thread() {
+ public void run() {
+ Statement s;
+ try {
+ s = c.createStatement();
+ assertTrue(s.execute("select part_id from parts"));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ t.start();
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+
+ sourceCounter.acquire();
+
+ //t should now be waiting also
+
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+
+ //t should finish
+ t.join();
+
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
+ @Test public void testWaitMultiple() throws Throwable {
+ final Connection c = server.createConnection("jdbc:teiid:test");
+
+ Thread t = new Thread() {
+ public void run() {
+ Statement s;
+ try {
+ s = c.createStatement();
+ assertTrue(s.execute("select part_id from parts union all select part_id
from parts"));
+ ResultSet r = s.getResultSet();
+
+ //wake up the other source thread, should put the requestworkitem into the more
work state
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+ Thread.sleep(1000); //TODO: need a better hook to determine that connector work
has finished
+ while (r.next()) {
+ //will hang unless this thread is allowed to resume processing
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ t.start();
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+
+ sourceCounter.acquire(2);
+
+ //t should now be waiting also
+
+ //wake up 1 source thread
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+
+ t.join();
+
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
}
Modified:
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java
===================================================================
---
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -615,6 +615,12 @@
ResultSet rs = dbmd.getTables(null, "SYSTEM",
"VIRTUALDATABASES", null); //$NON-NLS-1$ //$NON-NLS-2$
compareResultSet(rs);
}
+
+ @Test
+ public void testGetTables_noTypes() throws Exception {
+ ResultSet rs = dbmd.getTables(null, "SYSTEM",
"VIRTUALDATABASES", new String[0]); //$NON-NLS-1$ //$NON-NLS-2$
+ assertFalse(rs.next());
+ }
@Test
public void testGetTables_specificTableTypes() throws Exception {
Modified:
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
===================================================================
---
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2011-07-22
16:26:08 UTC (rev 3327)
@@ -222,6 +222,12 @@
TestMMDatabaseMetaData.compareResultSet(rs);
}
+ @Test public void testColumnMetadataWithAlias() throws Exception {
+ PreparedStatement stmt = conn.prepareStatement("select ta.attname as x from
pg_catalog.pg_attribute ta limit 1");
+ ResultSet rs = stmt.executeQuery();
+ TestMMDatabaseMetaData.compareResultSet(rs);
+ }
+
@Test public void testPreparedError() throws Exception {
PreparedStatement stmt = conn.prepareStatement("select cast(? as integer)");
stmt.setString(1, "a");
@@ -255,6 +261,13 @@
assertEquals("oid", rs.getArray("proargtypes").getBaseTypeName());
}
+ // this does not work as JDBC always sends the queries in prepared form
+ public void testPgDeclareCursor() throws Exception {
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery("begin;declare \"foo\" cursor for
select * from pg_proc;fetch 10 in \"foo\"; close \"foo\"");
+ rs.next();
+ }
+
@Test public void testPgProcedure() throws Exception {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select has_function_privilege(100,
'foo')");
Property changes on:
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
___________________________________________________________________
Modified: svn:mergeinfo
-
/branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java:3149-3217
+
/branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java:3149-3217,3281-3325
Added:
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected
===================================================================
---
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected
(rev 0)
+++
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected 2011-07-22
16:26:08 UTC (rev 3327)
@@ -0,0 +1,6 @@
+varchar
+x
+PART_ID
+Row Count : 1
+getColumnName getColumnType getCatalogName getColumnClassName getColumnLabel
getColumnTypeName getSchemaName getTableName getColumnDisplaySize getPrecision
getScale isAutoIncrement isCaseSensitive isCurrency isDefinitelyWritable isNullable
isReadOnly isSearchable isSigned isWritable
+x 12 java.lang.String x varchar
2147483647 0 0
false true false false 1 false
true false true
Modified:
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected
===================================================================
---
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected 2011-07-22
16:26:08 UTC (rev 3327)
@@ -1,10 +1,10 @@
varchar int2 varchar
varchar
varchar
-name attnum tablename
schemaname
tablename
+attname attnum relname
nspname
relname
oid 1 pg_attribute
pg_catalog
pg_attribute
Row Count : 1
getColumnName getColumnType getCatalogName getColumnClassName getColumnLabel
getColumnTypeName getSchemaName getTableName getColumnDisplaySize getPrecision
getScale isAutoIncrement isCaseSensitive isCurrency isDefinitelyWritable isNullable
isReadOnly isSearchable isSigned isWritable
-name 12 java.lang.String name varchar
2147483647 0 0
false true false false 0 false
true false true
+attname 12 java.lang.String attname varchar
2147483647 0 0
false true false false 0 false
true false true
attnum 5 java.lang.Integer attnum int2
6 5 0
false false false false 2 false
true true true
-tablename 12 java.lang.String tablename varchar
2147483647 0 0
false true false false 0 false
true false true
-schemaname 12 java.lang.String schemaname varchar
2147483647 0 0
false true false false 1 false
true false true
-tablename 12 java.lang.String tablename varchar
2147483647 0 0
false true false false 0 false
true false true
+relname 12 java.lang.String relname varchar
2147483647 0 0
false true false false 0 false
true false true
+nspname 12 java.lang.String nspname varchar
2147483647 0 0
false true false false 1 false
true false true
+relname 12 java.lang.String relname varchar
2147483647 0 0
false true false false 0 false
true false true
Property changes on:
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected
___________________________________________________________________
Added: svn:mergeinfo
+
/branches/7.4.x/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected:3281-3325
Modified:
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected
===================================================================
---
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected 2011-07-22
15:32:56 UTC (rev 3326)
+++
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected 2011-07-22
16:26:08 UTC (rev 3327)
@@ -1,10 +1,10 @@
varchar int2 varchar
varchar
varchar
-name attnum tablename
schemaname
tablename
+attname attnum relname
nspname
relname
oid 1 pg_attribute
pg_catalog
pg_attribute
Row Count : 1
getColumnName getColumnType getCatalogName getColumnClassName getColumnLabel
getColumnTypeName getSchemaName getTableName getColumnDisplaySize getPrecision
getScale isAutoIncrement isCaseSensitive isCurrency isDefinitelyWritable isNullable
isReadOnly isSearchable isSigned isWritable
-name 12 java.lang.String name varchar
2147483647 0 0
false true false false 0 false
true false true
+attname 12 java.lang.String attname varchar
2147483647 0 0
false true false false 0 false
true false true
attnum 5 java.lang.Integer attnum int2
6 5 0
false false false false 2 false
true true true
-tablename 12 java.lang.String tablename varchar
2147483647 0 0
false true false false 0 false
true false true
-schemaname 12 java.lang.String schemaname varchar
2147483647 0 0
false true false false 1 false
true false true
-tablename 12 java.lang.String tablename varchar
2147483647 0 0
false true false false 0 false
true false true
+relname 12 java.lang.String relname varchar
2147483647 0 0
false true false false 0 false
true false true
+nspname 12 java.lang.String nspname varchar
2147483647 0 0
false true false false 1 false
true false true
+relname 12 java.lang.String relname varchar
2147483647 0 0
false true false false 0 false
true false true
Property changes on:
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected
___________________________________________________________________
Added: svn:mergeinfo
+
/branches/7.4.x/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected:3281-3325