Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

forward merge of 7.6.1

  • Loading branch information...
commit 53bf29548c7136c27d8a3292b31cb070413c6b93 1 parent 503b51d
@shawkins shawkins authored
Showing with 634 additions and 283 deletions.
  1. +1 −0  build/kits/jboss-container/deployers/teiid.deployer/teiid-deployer-jboss-beans.xml
  2. +13 −11 build/kits/jboss-container/teiid-examples/dynamicvdb-ws-weather/README.txt
  3. +1 −1  build/kits/jboss-container/teiid-examples/dynamicvdb-ws-weather/weather-ds.xml
  4. +2 −1  build/kits/jboss-container/teiid-examples/dynamicvdb-ws-weather/weather-vdb.xml
  5. +1 −1  build/kits/jboss-container/teiid-examples/simpleclient/run.bat
  6. +5 −0 cache-jbosscache/pom.xml
  7. +36 −2 client/src/main/java/org/teiid/gss/MakeGSS.java
  8. +2 −0  client/src/main/resources/org/teiid/jdbc/i18n.properties
  9. +28 −0 connectors/connector-ws/src/main/java/org/teiid/resource/adapter/ws/WSConnectionImpl.java
  10. +2 −0  connectors/connector-ws/src/main/resources/org/teiid/resource/adapter/ws/i18n.properties
  11. +49 −0 connectors/connector-ws/src/test/java/org/teiid/resource/adapter/ws/TestWSAdapter.java
  12. +2 −2 connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
  13. +3 −2 connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
  14. +21 −1 connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java
  15. +5 −0 connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
  16. +8 −10 connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/Util.java
  17. +63 −34 ...ctors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/QueryExecutionImpl.java
  18. +99 −101 ...translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/visitors/CriteriaVisitor.java
  19. +25 −30 ...ranslator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/visitors/JoinQueryVisitor.java
  20. +11 −11 ...s/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/visitors/SelectVisitor.java
  21. +24 −0 ...s/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/TestQueryExecutionImpl.java
  22. +47 −14 ...rs/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java
  23. +1 −1  console/src/main/resources/META-INF/rhq-plugin.xml
  24. +12 −3 engine/src/main/java/org/teiid/common/buffer/impl/BufferFrontedFileStoreCache.java
  25. +1 −1  engine/src/main/java/org/teiid/dqp/internal/datamgr/ConnectorManager.java
  26. +40 −13 engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
  27. +1 −1  engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
  28. +0 −1  engine/src/main/java/org/teiid/query/sql/lang/Command.java
  29. +1 −0  engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
  30. +1 −0  engine/src/main/resources/org/teiid/query/i18n.properties
  31. +1 −1  engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java
  32. +10 −19 engine/src/test/java/org/teiid/query/parser/TestOptionsAndHints.java
  33. +12 −0 engine/src/test/java/org/teiid/query/processor/TestProcessor.java
  34. +21 −0 engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
  35. +1 −0  jboss-integration/src/main/java/org/teiid/jboss/TeiidAdd.java
  36. +5 −8 jboss-integration/src/main/java/org/teiid/jboss/TeiidOperationHandler.java
  37. +1 −1  jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
  38. +5 −0 pom.xml
  39. +67 −6 runtime/src/main/java/org/teiid/deployers/VDBStatusChecker.java
  40. +1 −3 runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
  41. +1 −1  runtime/src/main/java/org/teiid/transport/SSLConfiguration.java
  42. +1 −0  runtime/src/main/resources/org/teiid/runtime/i18n.properties
  43. +1 −1  runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
  44. +1 −1  runtime/src/test/java/org/teiid/transport/TestCommSockets.java
  45. +1 −1  test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
View
1  build/kits/jboss-container/deployers/teiid.deployer/teiid-deployer-jboss-beans.xml
@@ -88,6 +88,7 @@
<bean name="VDBStatusChecker" class="org.teiid.deployers.VDBStatusChecker">
<property name="VDBRepository"><inject bean="VDBRepository"/></property>
<property name="threadPool"><inject bean="jboss.system:service=ThreadPool"/></property>
+ <property name="translatorRepository"><inject bean="translatorRepository"/></property>
</bean>
<!-- Persistence class for the VDB deployment file -->
View
24 build/kits/jboss-container/teiid-examples/dynamicvdb-ws-weather/README.txt
@@ -38,18 +38,20 @@ select t.* from
2. SOAP11 RPC call providing all of the parameter values for the invoke procedure. With a SOAP
invocation, the action is used to convey the SOAPAction header value if needed. Also note
the use of the endpoint here with an absolute URL, which will be used instead of the default
-on the datasource.
+on the datasource. We are also using the DefaultServiceMode of MESSAGE (see the weather-vdb.xml file)
+to use the full SOAP message request and response.
select xmlserialize(document w.result as string) from
- (call weather.invoke(action=>'http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListZipCode',
- endpoint=>'http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php',
+ (call weather.invoke(action=>'http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php#LatLonListZipCode',
+ endpoint=>'http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php',
binding=>'SOAP11',
request=>'
- <ns1:LatLonListZipCode xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
- xmlns:ns1="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl">
- <zipCodeList xsi:type="ns2:zipCodeListType" xmlns:ns2="http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">63303</zipCodeList>
- </ns1:LatLonListZipCode>')) as w
-
-See the DatabaseMetadata on the invoke procedure for a full description of the parameters.
-
+ <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
+ <SOAP-ENV:Body>
+ <ns8077:LatLonListZipCode xmlns:ns8077="uri:DWMLgen">
+ <listZipCodeList xsi:type="xsd:string">20910 25414</listZipCodeList>
+ </ns8077:LatLonListZipCode>
+ </SOAP-ENV:Body>
+ </SOAP-ENV:Envelope>')) as w
+
+See the Reference or retrieve the JDBC DatabaseMetadata on the invoke procedure for a full description of the parameters.
View
2  build/kits/jboss-container/teiid-examples/dynamicvdb-ws-weather/weather-ds.xml
@@ -7,7 +7,7 @@
<rar-name>teiid-connector-ws.rar</rar-name>
<connection-definition>javax.resource.cci.ConnectionFactory</connection-definition>
- <config-property name="EndPoint">http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdXMLclient.php</config-property>
+ <config-property name="EndPoint">http://graphical.weather.gov/xml/sample_products/browser_interface/ndfdXMLclient.php</config-property>
<max-pool-size>20</max-pool-size>
View
3  build/kits/jboss-container/teiid-examples/dynamicvdb-ws-weather/weather-vdb.xml
@@ -2,7 +2,7 @@
<vdb name="weather" version="1">
<!--
- See the dynamicvdb Portfolio example, or http://community.jboss.org/wiki/DynamicVDBinTeiid70
+ See the dynamicvdb Portfolio example, or the Reference
for more information on the format of a vdb.xml file.
-->
@@ -16,6 +16,7 @@
<translator name="MessageWeather" type="ws">
<property name="DefaultBinding" value="HTTP"/>
+ <property name="DefaultServiceMode" value="MESSAGE"/>
</translator>
</vdb>
View
2  build/kits/jboss-container/teiid-examples/simpleclient/run.bat
@@ -2,7 +2,7 @@ rem First one sets the path for the client
set CLIENT_PATH=.
rem Second one adds the Teiid client
-set TEIID_PATH=../lib/teiid-${pom.version}-client.jar
+set TEIID_PATH=../../lib/teiid-${pom.version}-client.jar
java -cp %CLIENT_PATH%;%TEIID_PATH% JDBCClient %*
View
5 cache-jbosscache/pom.xml
@@ -34,6 +34,11 @@
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-clustering-jgroups</artifactId>
<scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jgroups</groupId>
+ <artifactId>jgroups</artifactId>
+ <scope>provided</scope>
</dependency>
</dependencies>
</project>
View
38 client/src/main/java/org/teiid/gss/MakeGSS.java
@@ -67,8 +67,42 @@ public static LogonResult authenticate(ILogon logon, Properties props)
Object result = null;
- String jaasApplicationName = props.getProperty(TeiidURL.CONNECTION.JAAS_NAME, "teiid"); //$NON-NLS-1$
- String kerberosPrincipalName = props.getProperty(TeiidURL.CONNECTION.KERBEROS_SERVICE_PRINCIPLE_NAME, "teiid"); //$NON-NLS-1$
+ StringBuilder errors = new StringBuilder();
+ String jaasApplicationName = props.getProperty(TeiidURL.CONNECTION.JAAS_NAME);
+ String nl = System.getProperty("line.separator");//$NON-NLS-1$
+ if (jaasApplicationName == null) {
+ errors.append(JDBCPlugin.Util.getString("client_prop_missing", TeiidURL.CONNECTION.JAAS_NAME)); //$NON-NLS-1$
+ errors.append(nl);
+ }
+
+ String kerberosPrincipalName = props.getProperty(TeiidURL.CONNECTION.KERBEROS_SERVICE_PRINCIPLE_NAME);
+ if (kerberosPrincipalName == null) {
+ errors.append(JDBCPlugin.Util.getString("client_prop_missing", TeiidURL.CONNECTION.KERBEROS_SERVICE_PRINCIPLE_NAME)); //$NON-NLS-1$
+ errors.append(nl);
+ }
+
+ String realm = System.getProperty("java.security.krb5.realm"); //$NON-NLS-1$
+ if (realm == null) {
+ errors.append(JDBCPlugin.Util.getString("system_prop_missing", "java.security.krb5.realm")); //$NON-NLS-1$ //$NON-NLS-2$
+ errors.append(nl);
+ }
+
+ String kdc = System.getProperty("java.security.krb5.kdc"); //$NON-NLS-1$
+ if (kdc == null) {
+ errors.append(JDBCPlugin.Util.getString("system_prop_missing", "java.security.krb5.kdc")); //$NON-NLS-1$ //$NON-NLS-2$
+ errors.append(nl);
+ }
+
+ String config = System.getProperty("java.security.auth.login.config"); //$NON-NLS-1$
+ if (config == null) {
+ errors.append(JDBCPlugin.Util.getString("system_prop_missing", "java.security.auth.login.config")); //$NON-NLS-1$ //$NON-NLS-2$
+ errors.append(nl);
+ }
+
+ if (errors.length() > 0) {
+ throw new LogonException(errors.toString());
+ }
+
String user = props.getProperty(TeiidURL.CONNECTION.USER_NAME);
String password = props.getProperty(TeiidURL.CONNECTION.PASSWORD);
View
2  client/src/main/resources/org/teiid/jdbc/i18n.properties
@@ -155,3 +155,5 @@ BatchSerializer.datatype_mismatch=The modeled datatype {0} for column {1} doesn'
no_krb_ticket=No cached kerberos ticket found and/or no password supplied
gss_auth_failed=GSS Authentication failed
setup_failed=Protocol error. Session setup failed.
+client_prop_missing=Client URL connection property missing "{0}". Please add the property to connection URL.
+system_prop_missing=System property "{0}" missing, please add using -D option on the VM startup script.
View
28 connectors/connector-ws/src/main/java/org/teiid/resource/adapter/ws/WSConnectionImpl.java
@@ -1,3 +1,25 @@
+/*
+ * 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.resource.adapter.ws;
import java.io.IOException;
@@ -188,6 +210,9 @@ public WSConnectionImpl(WSManagedConnectionFactory mcf) {
String defaultEndpoint = mcf.getEndPoint();
String defaultQueryString = null;
String defaultFragment = null;
+ if (defaultEndpoint == null) {
+ throw new WebServiceException(WSManagedConnectionFactory.UTIL.getString("null_default_endpoint")); //$NON-NLS-1$
+ }
String[] parts = defaultEndpoint.split("\\?", 2); //$NON-NLS-1$
defaultEndpoint = parts[0];
if (parts.length > 1) {
@@ -212,6 +237,9 @@ public WSConnectionImpl(WSManagedConnectionFactory mcf) {
}
} else {
endpoint = mcf.getEndPoint();
+ if (endpoint == null) {
+ throw new WebServiceException(WSManagedConnectionFactory.UTIL.getString("null_endpoint")); //$NON-NLS-1$
+ }
}
Dispatch<T> dispatch = null;
if (HTTPBinding.HTTP_BINDING.equals(binding) && type == DataSource.class) {
View
2  connectors/connector-ws/src/main/resources/org/teiid/resource/adapter/ws/i18n.properties
@@ -20,3 +20,5 @@
# 02110-1301 USA.
#
+null_endpoint=An endpoint must be specified by the procedure call or have a default value set by the EndPoint datasource property.
+null_default_endpoint=The use of a relative endpoint in a procedure call requires a a default endpoint on the datasource.
View
49 connectors/connector-ws/src/test/java/org/teiid/resource/adapter/ws/TestWSAdapter.java
@@ -0,0 +1,49 @@
+/*
+ * 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.resource.adapter.ws;
+
+import javax.resource.ResourceException;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.Service.Mode;
+import javax.xml.ws.http.HTTPBinding;
+
+import org.junit.Test;
+
+public class TestWSAdapter {
+
+ @Test(expected=WebServiceException.class) public void testMissingEndpoint() throws ResourceException {
+ WSManagedConnectionFactory wsmcf = new WSManagedConnectionFactory();
+
+ WSConnectionImpl conn = (WSConnectionImpl)wsmcf.createConnectionFactory().getConnection();
+ conn.createDispatch(HTTPBinding.HTTP_BINDING, null, StreamSource.class, Mode.PAYLOAD);
+ }
+
+ @Test(expected=WebServiceException.class) public void testMissingEndpoint1() throws ResourceException {
+ WSManagedConnectionFactory wsmcf = new WSManagedConnectionFactory();
+
+ WSConnectionImpl conn = (WSConnectionImpl)wsmcf.createConnectionFactory().getConnection();
+ conn.createDispatch(HTTPBinding.HTTP_BINDING, "/x", StreamSource.class, Mode.PAYLOAD); //$NON-NLS-1$
+ }
+
+}
View
4 connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
@@ -211,9 +211,9 @@ public void visit(Call obj) {
if (obj.getArguments().get(i).getDirection() != Direction.IN) {
throw new IllegalArgumentException(JDBCPlugin.Util.getString("SQLConversionVisitor.not_in_parameter", i+1)); //$NON-NLS-1$
}
- visit(obj.getArguments().get(i));
+ buffer.append('?');
if (this.prepared) {
- this.preparedValues.add(obj.getArguments());
+ this.preparedValues = obj.getArguments();
}
}
}
View
5 ...ranslator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
@@ -70,6 +70,7 @@
import org.teiid.translator.jdbc.JDBCExecutionFactory;
import org.teiid.translator.jdbc.JDBCPlugin;
import org.teiid.translator.jdbc.LocateFunctionModifier;
+import org.teiid.translator.jdbc.SQLConversionVisitor;
import org.teiid.translator.jdbc.TranslatedCommand;
@@ -606,8 +607,8 @@ public boolean isOracleSuppliedDriver() {
public List<?> translate(LanguageObject obj, ExecutionContext context) {
if (oracleSuppliedDriver && obj instanceof Call) {
Call call = (Call)obj;
- //oracle returns the resultset as a parameter
- if (call.getReturnType() == null) {
+ if (call.getReturnType() == null && call.getMetadataObject() != null && call.getMetadataObject().getProperties().get(SQLConversionVisitor.TEIID_NATIVE_QUERY) == null) {
+ //oracle returns the resultset as a parameter
call.setReturnType(RefCursorType.class);
}
}
View
22 .../translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java
@@ -27,6 +27,7 @@
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
+import java.sql.Types;
import java.util.Arrays;
import java.util.List;
@@ -875,11 +876,30 @@ public void helpTestVisitor(String vdb, String input, String expectedOutput) thr
@Test public void testNativeQueryProc() throws Exception {
String input = "call proc(2)"; //$NON-NLS-1$
- String output = "select x from y where z = 2"; //$NON-NLS-1$
+ String output = "select x from y where z = ?"; //$NON-NLS-1$
QueryMetadataInterface metadata = getOracleSpecificMetadata();
helpTestVisitor(metadata, input, EMPTY_CONTEXT, null, output);
}
+
+ @Test public void testNativeQueryProcPreparedExecution() throws Exception {
+ CommandBuilder commandBuilder = new CommandBuilder(getOracleSpecificMetadata());
+ Command command = commandBuilder.getCommand("call proc(2)");
+ Connection connection = Mockito.mock(Connection.class);
+ CallableStatement cs = Mockito.mock(CallableStatement.class);
+ Mockito.stub(cs.getUpdateCount()).toReturn(-1);
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Mockito.stub(cs.getObject(1)).toReturn(rs);
+ Mockito.stub(cs.getInt(3)).toReturn(4);
+ Mockito.stub(connection.prepareCall("select x from y where z = ?")).toReturn(cs); //$NON-NLS-1$
+ OracleExecutionFactory ef = new OracleExecutionFactory();
+
+ JDBCProcedureExecution procedureExecution = new JDBCProcedureExecution(command, connection, Mockito.mock(ExecutionContext.class), ef);
+ procedureExecution.execute();
+ Mockito.verify(cs, Mockito.never()).registerOutParameter(1, OracleExecutionFactory.CURSOR_TYPE);
+ Mockito.verify(cs, Mockito.never()).getObject(1);
+ Mockito.verify(cs, Mockito.times(1)).setObject(1, 2, Types.INTEGER);
+ }
}
View
5 ...-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
@@ -167,5 +167,10 @@ public boolean supportsOrCriteria() {
public boolean supportsCompareCriteriaOrdered() {
return true;
}
+
+ @Override
+ public boolean supportsIsNullCriteria() {
+ return true;
+ }
}
View
18 connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/Util.java
@@ -21,8 +21,8 @@
*/
package org.teiid.translator.salesforce;
-import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Date;
import org.teiid.translator.TranslatorException;
@@ -56,16 +56,14 @@ public static void validateQueryLength(StringBuffer query) throws TranslatorExce
}
}
- public static SimpleDateFormat getSalesforceDateTimeFormat() {
- return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); //$NON-NLS-1$
- }
+ private static String timeZone;
- public static SimpleDateFormat getTimeZoneOffsetFormat() {
- return new SimpleDateFormat("Z"); //$NON-NLS-1$
+ public static String getDefaultTimeZoneString() {
+ if (timeZone == null) {
+ String s = new SimpleDateFormat("Z").format(new Date(0)); //$NON-NLS-1$
+ timeZone = s.substring(0, 3) + ':' + s.substring(3, 5);
+ }
+ return timeZone;
}
- public static DateFormat getSalesforceDateFormat() {
- return new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
- }
-
}
View
97 ...alesforce/src/main/java/org/teiid/translator/salesforce/execution/QueryExecutionImpl.java
@@ -21,18 +21,23 @@
*/
package org.teiid.translator.salesforce.execution;
+import java.sql.Time;
import java.sql.Timestamp;
-import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.resource.ResourceException;
+import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.AggregateFunction;
import org.teiid.language.Join;
import org.teiid.language.QueryExpression;
@@ -51,7 +56,6 @@
import org.teiid.translator.TranslatorException;
import org.teiid.translator.salesforce.SalesForcePlugin;
import org.teiid.translator.salesforce.SalesforceConnection;
-import org.teiid.translator.salesforce.Util;
import org.teiid.translator.salesforce.execution.visitors.JoinQueryVisitor;
import org.teiid.translator.salesforce.execution.visitors.SelectVisitor;
import org.w3c.dom.Element;
@@ -63,6 +67,8 @@
public class QueryExecutionImpl implements ResultSetExecution {
+ private static final Pattern dateTimePattern = Pattern.compile("^(?:(\\d{4}-\\d{2}-\\d{2})T)?(\\d{2}:\\d{2}:\\d{2}(?:.\\d+)?)(.*)"); //$NON-NLS-1$
+
private static final String SF_ID = "sf:Id"; //$NON-NLS-1$
private static final String SF_TYPE = "sf:type"; //$NON-NLS-1$
@@ -78,7 +84,6 @@
private RuntimeMetadata metadata;
private ExecutionContext context;
-
private SelectVisitor visitor;
@@ -103,6 +108,8 @@
private int topResultIndex = 0;
+ private Calendar cal;
+
public QueryExecutionImpl(QueryExpression command, SalesforceConnection connection, RuntimeMetadata metadata, ExecutionContext context) {
this.connection = connection;
this.metadata = metadata;
@@ -355,7 +362,7 @@ private void logAndMapFields(String sObjectName,
}
}
- private void logFields(String sObjectName, List<Object> fields) throws TranslatorException {
+ private void logFields(String sObjectName, List<Object> fields) {
if (!LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL)) {
return;
}
@@ -369,53 +376,75 @@ private void logFields(String sObjectName, List<Object> fields) throws Translato
}
+ /**
+ * TODO: the logic here should be aware of xsi:type information and use a standard conversion
+ * library. Conversion to teiid types should then be a secondary effort - and will be automatically handled above here.
+ */
@SuppressWarnings("unchecked")
private Object getCellDatum(Column element, Element elem) throws TranslatorException {
if(!element.getNameInSource().equals(elem.getLocalName())) {
throw new TranslatorException(SalesForcePlugin.Util.getString("SalesforceQueryExecutionImpl.column.mismatch1") + element.getNameInSource() + SalesForcePlugin.Util.getString("SalesforceQueryExecutionImpl.column.mismatch2") + elem.getLocalName()); //$NON-NLS-1$ //$NON-NLS-2$
}
+ if (Boolean.parseBoolean(elem.getAttribute(XSI_NIL))) {
+ return null;
+ }
String value = elem.getTextContent();
- Object result = null;
+ Object result = value;
Class type = element.getJavaType();
if(type.equals(String.class)) {
result = value;
- }
- else if (type.equals(Boolean.class)) {
- result = Boolean.valueOf(value);
- } else if (type.equals(Double.class)) {
- if (null != value) {
- if(!value.isEmpty()) {
- result = Double.valueOf(value);
- }
- }
- } else if (type.equals(Integer.class)) {
- if (null != value) {
- if(!value.isEmpty()) {
- result = Integer.valueOf(value);
+ } else if (!value.isEmpty()) {
+ result = value;
+ if (type.equals(java.sql.Timestamp.class) || type.equals(java.sql.Time.class)) {
+ if (cal == null) {
+ cal = Calendar.getInstance();
}
+ result = parseDateTime(value, type, cal);
}
- } else if (type.equals(java.sql.Date.class)) {
- if (null != value) {
- if(!value.isEmpty()) {
- result = java.sql.Date.valueOf(value);
+ }
+ return result;
+ }
+
+ static Object parseDateTime(String value, Class<?> type, Calendar cal)
+ throws TranslatorException {
+ try {
+ Matcher m = dateTimePattern.matcher(value);
+ if (m.matches()) {
+ String date = m.group(1);
+ String time = m.group(2);
+ String timeZone = m.group(3);
+ Date d = null;
+ if (date == null) {
+ //sql times don't care about fractional seconds
+ int milli = time.lastIndexOf('.');
+ if (milli > 0) {
+ time = time.substring(0, milli);
+ }
+ d = Time.valueOf(time);
+ } else {
+ d = Timestamp.valueOf(date + " " + time); //$NON-NLS-1$
}
- }
- } else if (type.equals(java.sql.Timestamp.class)) {
- if (null != value) {
- if(!value.isEmpty()) {
- try {
- Date date = Util.getSalesforceDateTimeFormat().parse(value);
- result = new Timestamp(date.getTime());
- } catch (ParseException e) {
- throw new TranslatorException(e, SalesForcePlugin.Util.getString("SalesforceQueryExecutionImpl.datatime.parse") + value); //$NON-NLS-1$
+ TimeZone tz = null;
+ if (timeZone != null) {
+ if (timeZone.equals("Z")) { //$NON-NLS-1$
+ tz = TimeZone.getTimeZone("GMT"); //$NON-NLS-1$
+ } else if (timeZone.contains(":")) { //$NON-NLS-1$
+ tz = TimeZone.getTimeZone("GMT" + timeZone); //$NON-NLS-1$
+ } else {
+ //this is probably an exceptional case
+ tz = TimeZone.getTimeZone(timeZone);
}
+ cal.setTimeZone(tz);
+ } else {
+ cal = null;
}
+ return TimestampWithTimezone.create(d, TimeZone.getDefault(), cal, type);
}
- } else {
- result = value;
+ throw new TranslatorException(SalesForcePlugin.Util.getString("SalesforceQueryExecutionImpl.datatime.parse") + value); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ throw new TranslatorException(e, SalesForcePlugin.Util.getString("SalesforceQueryExecutionImpl.datatime.parse") + value); //$NON-NLS-1$
}
- return result;
}
private boolean isSObject(Element element) {
View
200 ...rce/src/main/java/org/teiid/translator/salesforce/execution/visitors/CriteriaVisitor.java
@@ -24,18 +24,21 @@
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.AndOr;
import org.teiid.language.ColumnReference;
import org.teiid.language.Comparison;
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.In;
+import org.teiid.language.IsNull;
import org.teiid.language.Like;
import org.teiid.language.Literal;
import org.teiid.language.NamedTable;
@@ -80,7 +83,7 @@
protected Table table;
boolean onlyIDCriteria;
protected Boolean queryAll = Boolean.FALSE;
-
+
// support for invoking a retrieve when possible.
protected In idInCriteria = null;
@@ -98,31 +101,26 @@ public CriteriaVisitor( RuntimeMetadata metadata ) {
@Override
public void visit( Comparison criteria ) {
- super.visit(criteria);
- try {
- addCompareCriteria(criteriaList, criteria);
- boolean isAcceptableID = (Operator.EQ == criteria.getOperator() && isIdColumn(criteria.getLeftExpression()));
- setHasCriteria(true, isAcceptableID);
- if (isAcceptableID) {
- this.idInCriteria = new In(criteria.getLeftExpression(), Arrays.asList(criteria.getRightExpression()), false);
- }
- } catch (TranslatorException e) {
- exceptions.add(e);
+ addCompareCriteria(criteria);
+ boolean isAcceptableID = (Operator.EQ == criteria.getOperator() && isIdColumn(criteria.getLeftExpression()));
+ setHasCriteria(true, isAcceptableID);
+ if (isAcceptableID) {
+ this.idInCriteria = new In(criteria.getLeftExpression(), Arrays.asList(criteria.getRightExpression()), false);
}
}
-
+
+ public void visit(IsNull obj) {
+ visit(new Comparison(obj.getExpression(), new Literal(null, obj.getExpression().getType()), obj.isNegated()?Comparison.Operator.NE:Comparison.Operator.EQ));
+ }
+
@Override
public void visit( Like criteria ) {
- try {
- if (isIdColumn(criteria.getLeftExpression())) {
- TranslatorException e = new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.LIKE.not.supported.on.Id")); //$NON-NLS-1$
- exceptions.add(e);
- }
- if (isMultiSelectColumn(criteria.getLeftExpression())) {
- TranslatorException e = new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.LIKE.not.supported.on.multiselect")); //$NON-NLS-1$
- exceptions.add(e);
- }
- } catch (TranslatorException e) {
+ if (isIdColumn(criteria.getLeftExpression())) {
+ TranslatorException e = new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.LIKE.not.supported.on.Id")); //$NON-NLS-1$
+ exceptions.add(e);
+ }
+ if (isMultiSelectColumn(criteria.getLeftExpression())) {
+ TranslatorException e = new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.LIKE.not.supported.on.multiselect")); //$NON-NLS-1$
exceptions.add(e);
}
boolean negated = criteria.isNegated();
@@ -135,7 +133,7 @@ public void visit( Like criteria ) {
// don't check if it's ID, Id LIKE '123%' still requires a query
setHasCriteria(true, false);
}
-
+
@Override
public void visit(AndOr obj) {
List<String> savedCriteria = new LinkedList<String>();
@@ -170,23 +168,19 @@ private void addNot() {
@Override
public void visit( In criteria ) {
- try {
- Expression lExpr = criteria.getLeftExpression();
- if (lExpr instanceof ColumnReference) {
- ColumnReference cr = (ColumnReference)lExpr;
- Column column = cr.getMetadataObject();
- if (column != null && (MULTIPICKLIST.equalsIgnoreCase(column.getNativeType()) || RESTRICTEDMULTISELECTPICKLIST.equalsIgnoreCase(column.getNativeType()))) {
- appendMultiselectIn(column, criteria);
- } else {
- appendCriteria(criteria);
- }
+ Expression lExpr = criteria.getLeftExpression();
+ if (lExpr instanceof ColumnReference) {
+ ColumnReference cr = (ColumnReference)lExpr;
+ Column column = cr.getMetadataObject();
+ if (column != null && (MULTIPICKLIST.equalsIgnoreCase(column.getNativeType()) || RESTRICTEDMULTISELECTPICKLIST.equalsIgnoreCase(column.getNativeType()))) {
+ appendMultiselectIn(column, criteria);
} else {
- appendCriteria(criteria);
+ appendCriteria(criteria);
}
- setHasCriteria(true, isIdColumn(criteria.getLeftExpression()));
- } catch (TranslatorException e) {
- exceptions.add(e);
+ } else {
+ appendCriteria(criteria);
}
+ setHasCriteria(true, isIdColumn(criteria.getLeftExpression()));
}
public void parseFunction( Function func ) {
@@ -215,7 +209,7 @@ private void generateMultiSelect( Function func,
}
private void appendMultiselectIn( Column column,
- In criteria ) throws TranslatorException {
+ In criteria ) {
StringBuffer result = new StringBuffer();
result.append(column.getNameInSource()).append(SPACE);
if (criteria.isNegated()) {
@@ -270,9 +264,8 @@ private void addFunctionParams( Literal param,
}
criterion.append(CLOSE);
}
-
- protected void addCompareCriteria( List criteriaList,
- Comparison compCriteria ) throws TranslatorException {
+
+ protected void addCompareCriteria(Comparison compCriteria ) {
Expression lExpr = compCriteria.getLeftExpression();
if (lExpr instanceof Function) {
parseFunction((Function)lExpr);
@@ -280,38 +273,13 @@ protected void addCompareCriteria( List criteriaList,
ColumnReference left = (ColumnReference)lExpr;
Column column = left.getMetadataObject();
String columnName = column.getNameInSource();
- StringBuffer queryString = new StringBuffer();
- queryString.append(column.getParent().getNameInSource());
- queryString.append('.');
- queryString.append(columnName).append(SPACE);
+ StringBuilder queryString = new StringBuilder();
+ appendColumnReference(queryString, left);
+ queryString.append(SPACE);
queryString.append(comparisonOperators.get(compCriteria.getOperator()));
queryString.append(' ');
Expression rExp = compCriteria.getRightExpression();
- if(rExp instanceof Literal) {
- Literal literal = (Literal)rExp;
- if (column.getJavaType().equals(Boolean.class)) {
- queryString.append(((Boolean)literal.getValue()).toString());
- } else if (column.getJavaType().equals(java.sql.Timestamp.class)) {
- Timestamp datetime = (java.sql.Timestamp)literal.getValue();
- String value = Util.getSalesforceDateTimeFormat().format(datetime);
- String zoneValue = Util.getTimeZoneOffsetFormat().format(datetime);
- queryString.append(value).append(zoneValue.subSequence(0, 3)).append(':').append(zoneValue.subSequence(3, 5));
- } else if (column.getJavaType().equals(java.sql.Time.class)) {
- String value = Util.getSalesforceDateTimeFormat().format((java.sql.Time)literal.getValue());
- queryString.append(value);
- } else if (column.getJavaType().equals(java.sql.Date.class)) {
- String value = Util.getSalesforceDateFormat().format((java.sql.Date)literal.getValue());
- queryString.append(value);
- } else {
- queryString.append(compCriteria.getRightExpression().toString());
- }
- } else if(rExp instanceof ColumnReference) {
- ColumnReference right = (ColumnReference)lExpr;
- column = left.getMetadataObject();
- columnName = column.getNameInSource();
- queryString.append(columnName);
- }
-
+ queryString.append(getValue(rExp, false));
criteriaList.add(queryString.toString());
if (columnName.equals("IsDeleted")) { //$NON-NLS-1$
@@ -324,56 +292,86 @@ protected void addCompareCriteria( List criteriaList,
}
}
- private void appendCriteria( In criteria ) throws TranslatorException {
+ private void appendColumnReference(StringBuilder queryString,
+ ColumnReference ref) {
+ queryString.append(ref.getMetadataObject().getParent().getNameInSource());
+ queryString.append('.');
+ queryString.append(ref.getMetadataObject().getNameInSource());
+ }
+
+ private void appendCriteria( In criteria ) {
StringBuffer queryString = new StringBuffer();
Expression leftExp = criteria.getLeftExpression();
if(isIdColumn(leftExp)) {
idInCriteria = criteria;
}
- queryString.append(getValue(leftExp));
+ queryString.append(getValue(leftExp, false));
queryString.append(' ');
if (criteria.isNegated()) {
queryString.append("NOT "); //$NON-NLS-1$
}
queryString.append("IN"); //$NON-NLS-1$
queryString.append('(');
- Column column = ((ColumnReference)criteria.getLeftExpression()).getMetadataObject();
- boolean timeColumn = isTimeColumn(column);
- boolean first = true;
- Iterator iter = criteria.getRightExpressions().iterator();
+ Iterator<Expression> iter = criteria.getRightExpressions().iterator();
while (iter.hasNext()) {
- if (!first) queryString.append(',');
- if (!timeColumn) queryString.append('\'');
- queryString.append(getValue((Expression)iter.next()));
- if (!timeColumn) queryString.append('\'');
- first = false;
+ queryString.append(getValue(iter.next(), false));
+ if (iter.hasNext()) {
+ queryString.append(',');
+ }
}
queryString.append(')');
criteriaList.add(queryString.toString());
}
-
- private boolean isTimeColumn( Column column ) throws TranslatorException {
- boolean result = false;
- if (column.getJavaType().equals(java.sql.Timestamp.class) || column.getJavaType().equals(java.sql.Time.class)
- || column.getJavaType().equals(java.sql.Date.class)) {
- result = true;
- }
- return result;
- }
-
- protected String getValue( Expression expr ) throws TranslatorException {
- String result;
+
+ protected String getValue( Expression expr, boolean raw) {
+ StringBuilder result = new StringBuilder();
if (expr instanceof ColumnReference) {
- ColumnReference element = (ColumnReference)expr;
- Column element2 = element.getMetadataObject();
- result = element2.getNameInSource();
+ appendColumnReference(result, (ColumnReference)expr);
} else if (expr instanceof Literal) {
- Literal literal = (Literal)expr;
- result = literal.getValue().toString();
+ Literal literal = (Literal)expr;
+ if (literal.getValue() == null) {
+ if (raw) {
+ return null;
+ }
+ return "NULL"; //$NON-NLS-1$
+ }
+ if (raw) {
+ return literal.getValue().toString();
+ }
+ if (literal.getValue().getClass().equals(Boolean.class)) {
+ result.append(((Boolean)literal.getValue()).toString());
+ } else if (literal.getValue().getClass().equals(java.sql.Timestamp.class)) {
+ Timestamp datetime = (java.sql.Timestamp)literal.getValue();
+ String value = datetime.toString();
+ int fractionalPlace = value.lastIndexOf('.');
+ int fractionalLength = value.length() - fractionalPlace - 1;
+ if (fractionalLength > 3) {
+ value = value.substring(0, fractionalPlace + 3);
+ } else if (fractionalLength < 3) {
+ value += "00".substring(fractionalLength - 1); //$NON-NLS-1$
+ }
+ result.append(value).setCharAt(result.length()-value.length()+10, 'T');
+ Calendar c = TimestampWithTimezone.getCalendar();
+ c.setTime(datetime);
+ int minutes = (c.get(Calendar.ZONE_OFFSET) +
+ c.get(Calendar.DST_OFFSET)) / 60000;
+ int val = minutes/60;
+ result.append(String.format("%1$+03d", val)); //$NON-NLS-1$
+ result.append(':');
+ val = minutes%60;
+ result.append(val/10);
+ result.append(val%10);
+ } else if (literal.getValue().getClass().equals(java.sql.Time.class)) {
+ result.append(literal.getValue()).append(".000").append(Util.getDefaultTimeZoneString()); //$NON-NLS-1$
+ } else if (literal.getValue().getClass().equals(java.sql.Date.class)) {
+ result.append(literal.getValue());
+ } else {
+ result.append(expr.toString());
+ }
} else {
throw new RuntimeException("unknown type in SalesforceQueryExecution.getValue(): " + expr.toString()); //$NON-NLS-1$
}
- return result;
+ return result.toString();
}
protected void loadColumnMetadata( NamedTable group ) throws TranslatorException {
@@ -394,7 +392,7 @@ protected void loadColumnMetadata( NamedTable group ) throws TranslatorException
}
}
- protected boolean isIdColumn( Expression expression ) throws TranslatorException {
+ protected boolean isIdColumn( Expression expression ) {
boolean result = false;
if (expression instanceof ColumnReference) {
Column element = ((ColumnReference)expression).getMetadataObject();
@@ -406,7 +404,7 @@ protected boolean isIdColumn( Expression expression ) throws TranslatorException
return result;
}
- protected boolean isMultiSelectColumn( Expression expression ) throws TranslatorException {
+ protected boolean isMultiSelectColumn( Expression expression ) {
boolean result = false;
if (expression instanceof ColumnReference) {
Column element = ((ColumnReference)expression).getMetadataObject();
View
55 ...ce/src/main/java/org/teiid/translator/salesforce/execution/visitors/JoinQueryVisitor.java
@@ -63,39 +63,34 @@ public void visit(Join join) {
@Override
public void visit(Comparison criteria) {
-
// Find the criteria that joins the two tables
- try {
- Expression rExp = criteria.getRightExpression();
- if (rExp instanceof ColumnReference) {
- Expression lExp = criteria.getLeftExpression();
- if (isIdColumn(rExp) || isIdColumn(lExp)) {
-
- Column rColumn = ((ColumnReference) rExp).getMetadataObject();
- String rTableName = rColumn.getParent().getNameInSource();
-
- Column lColumn = ((ColumnReference) lExp).getMetadataObject();
- String lTableName = lColumn.getParent().getNameInSource();
-
- if (leftTableInJoin.getNameInSource().equals(rTableName)
- || leftTableInJoin.getNameInSource().equals(lTableName)
- && rightTableInJoin.getNameInSource().equals(rTableName)
- || rightTableInJoin.getNameInSource().equals(lTableName)
- && !rTableName.equals(lTableName)) {
- // This is the join criteria, the one that is the ID is the parent.
- Expression fKey = !isIdColumn(lExp) ? lExp : rExp;
- table = childTable = (Table)((ColumnReference) fKey).getMetadataObject().getParent();
- } else {
- // Only add the criteria to the query if it is not the join criteria.
- // The join criteria is implicit in the salesforce syntax.
- super.visit(criteria);
- }
+ Expression rExp = criteria.getRightExpression();
+ if (rExp instanceof ColumnReference) {
+ Expression lExp = criteria.getLeftExpression();
+ if (isIdColumn(rExp) || isIdColumn(lExp)) {
+
+ Column rColumn = ((ColumnReference) rExp).getMetadataObject();
+ String rTableName = rColumn.getParent().getNameInSource();
+
+ Column lColumn = ((ColumnReference) lExp).getMetadataObject();
+ String lTableName = lColumn.getParent().getNameInSource();
+
+ if (leftTableInJoin.getNameInSource().equals(rTableName)
+ || leftTableInJoin.getNameInSource().equals(lTableName)
+ && rightTableInJoin.getNameInSource().equals(rTableName)
+ || rightTableInJoin.getNameInSource().equals(lTableName)
+ && !rTableName.equals(lTableName)) {
+ // This is the join criteria, the one that is the ID is the parent.
+ Expression fKey = !isIdColumn(lExp) ? lExp : rExp;
+ table = childTable = (Table)((ColumnReference) fKey).getMetadataObject().getParent();
+ } else {
+ // Only add the criteria to the query if it is not the join criteria.
+ // The join criteria is implicit in the salesforce syntax.
+ super.visit(criteria);
}
- } else {
- super.visit(criteria);
}
- } catch (TranslatorException e) {
- exceptions.add(e);
+ } else {
+ super.visit(criteria);
}
}
View
22 ...force/src/main/java/org/teiid/translator/salesforce/execution/visitors/SelectVisitor.java
@@ -61,7 +61,7 @@ public SelectVisitor(RuntimeMetadata metadata) {
public void visit(Select query) {
super.visit(query);
if (query.isDistinct()) {
- exceptions.add(new TranslatorException(SalesForcePlugin.Util.getString("SelectVisitor.distinct.not.supported")));
+ exceptions.add(new TranslatorException(SalesForcePlugin.Util.getString("SelectVisitor.distinct.not.supported"))); //$NON-NLS-1$
}
selectSymbols = query.getDerivedColumns();
selectSymbolCount = selectSymbols.size();
@@ -78,10 +78,10 @@ public void visit(Select query) {
selectSymbolNameToIndex .put(qualifiedName, index);
String nameInSource = element.getNameInSource();
if (null == nameInSource || nameInSource.length() == 0) {
- exceptions.add(new TranslatorException("name in source is null or empty for column "+ symbol.toString()));
+ exceptions.add(new TranslatorException("name in source is null or empty for column "+ symbol.toString())); //$NON-NLS-1$
continue;
}
- if (nameInSource.equalsIgnoreCase("id")) {
+ if (nameInSource.equalsIgnoreCase("id")) { //$NON-NLS-1$
idIndex = index;
}
}
@@ -96,7 +96,7 @@ public void visit(NamedTable obj) {
String supportsQuery = table.getProperties().get(Constants.SUPPORTS_QUERY);
objectSupportsRetrieve = Boolean.valueOf(table.getProperties().get(Constants.SUPPORTS_RETRIEVE));
if (!Boolean.valueOf(supportsQuery)) {
- throw new TranslatorException(table.getNameInSource() + " " + SalesForcePlugin.Util.getString("CriteriaVisitor.query.not.supported"));
+ throw new TranslatorException(table.getNameInSource() + " " + SalesForcePlugin.Util.getString("CriteriaVisitor.query.not.supported")); //$NON-NLS-1$ //$NON-NLS-2$
}
loadColumnMetadata(obj);
} catch (TranslatorException ce) {
@@ -118,7 +118,7 @@ public void visit(Limit obj) {
public String getQuery() throws TranslatorException {
if (!exceptions.isEmpty()) {
- throw ((TranslatorException) exceptions.get(0));
+ throw exceptions.get(0);
}
StringBuffer result = new StringBuffer();
result.append(SELECT).append(SPACE);
@@ -137,9 +137,9 @@ private void addSelectSymbols(StringBuffer result) throws TranslatorException {
boolean firstTime = true;
for (DerivedColumn symbol : selectSymbols) {
if (!firstTime) {
- result.append(", ");
+ result.append(", "); //$NON-NLS-1$
} else {
- firstTime = false;
+ firstTime = false;
}
Expression expression = symbol.getExpression();
if (expression instanceof ColumnReference) {
@@ -153,7 +153,7 @@ private void addSelectSymbols(StringBuffer result) throws TranslatorException {
if(parent instanceof Table) {
table = (Table)parent;
} else {
- throw new TranslatorException("Could not resolve Table for column " + element.getName());
+ throw new TranslatorException("Could not resolve Table for column " + element.getName()); //$NON-NLS-1$
}
}
result.append(table.getNameInSource());
@@ -209,19 +209,19 @@ public String getRetrieveFieldList() throws TranslatorException {
}
- public List<String> getIdInCriteria() throws TranslatorException {
+ public List<String> getIdInCriteria() {
assertRetrieveValidated();
List<Expression> expressions = this.idInCriteria.getRightExpressions();
List<String> result = new ArrayList<String>(expressions.size());
for(int i = 0; i < expressions.size(); i++) {
- result.add(getValue(expressions.get(i)));
+ result.add(getValue(expressions.get(i), true));
}
return result;
}
private void assertRetrieveValidated() throws AssertionError {
if(!hasOnlyIDCriteria()) {
- throw new AssertionError("Must call hasOnlyIdInCriteria() before this method");
+ throw new AssertionError("Must call hasOnlyIdInCriteria() before this method"); //$NON-NLS-1$
}
}
View
24 ...force/src/test/java/org/teiid/translator/salesforce/execution/TestQueryExecutionImpl.java
@@ -24,11 +24,19 @@
import static org.junit.Assert.*;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.teiid.cdk.api.TranslationUtility;
import org.teiid.language.Select;
import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.query.unittest.TimestampUtil;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.salesforce.SalesforceConnection;
import org.teiid.translator.salesforce.execution.visitors.TestVisitors;
@@ -66,4 +74,20 @@
assertNull(qei.next());
}
+ @BeforeClass static public void oneTimeSetup() {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT-06:00"));
+ }
+
+ @AfterClass static public void oneTimeTearDown() {
+ TimeZone.setDefault(null);
+ }
+
+ @Test public void testValueParsing() throws Exception {
+ assertEquals(TimestampUtil.createTime(2, 0, 0), QueryExecutionImpl.parseDateTime("08:00:00.000Z", Time.class, Calendar.getInstance()));
+ }
+
+ @Test public void testValueParsing1() throws Exception {
+ assertEquals(TimestampUtil.createTimestamp(101, 0, 1, 2, 0, 0, 1000000), QueryExecutionImpl.parseDateTime("2001-01-01T08:00:00.001Z", Timestamp.class, Calendar.getInstance()));
+ }
+
}
View
61 ...sforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java
@@ -28,6 +28,8 @@
import java.util.List;
import java.util.TimeZone;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.teiid.cdk.api.TranslationUtility;
@@ -90,16 +92,16 @@ public static QueryMetadataInterface exampleSalesforce() {
contactTable.setProperty("Supports Query", Boolean.TRUE.toString()); //$NON-NLS-1$
// Create Contact Columns
String[] elemNames = new String[] {
- "ContactID", "Name", "AccountId", "InitialContact" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "ContactID", "Name", "AccountId", "InitialContact", "LastTime" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
};
String[] elemTypes = new String[] {
- DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.TIMESTAMP
+ DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.TIMESTAMP, DataTypeManager.DefaultDataTypes.TIME
};
List<Column> contactCols = RealMetadataFactory.createElements(contactTable, elemNames, elemTypes);
// Set name in source on each column
String[] contactNameInSource = new String[] {
- "id", "ContactName", "accountid", "InitialContact" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "id", "ContactName", "accountid", "InitialContact", "LastTime" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
};
for(int i=0; i<2; i++) {
Column obj = contactCols.get(i);
@@ -154,7 +156,7 @@ public static QueryMetadataInterface exampleSalesforce() {
SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
visitor.visit(command);
assertFalse(visitor.hasOnlyIDCriteria());
- assertEquals("SELECT Account.id, Account.AccountName, Account.Stuff, Account.Industry FROM Account WHERE Industry IN('1','2','3')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ assertEquals("SELECT Account.id, Account.AccountName, Account.Stuff, Account.Industry FROM Account WHERE Account.Industry IN('1','2','3')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
@@ -194,7 +196,21 @@ public static QueryMetadataInterface exampleSalesforce() {
Select command = (Select)translationUtility.parseCommand("SELECT Contacts.Name FROM Contacts WHERE Contacts.Name in ('x', 'y')"); //$NON-NLS-1$
SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
visitor.visit(command);
- assertEquals("SELECT Contact.ContactName FROM Contact WHERE ContactName IN('x','y')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.ContactName IN('x','y')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ }
+
+ @Test public void testEqualsElement() throws Exception {
+ Select command = (Select)translationUtility.parseCommand("SELECT Contacts.Name FROM Contacts WHERE Contacts.Name = Contacts.AccountId"); //$NON-NLS-1$
+ SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.ContactName = Contact.AccountId", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ }
+
+ @Test public void testIsNull() throws Exception {
+ Select command = (Select)translationUtility.parseCommand("SELECT Contacts.Name FROM Contacts WHERE Contacts.Name is not null"); //$NON-NLS-1$
+ SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.ContactName != NULL", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
@Test public void testIDCriteria() throws Exception {
@@ -205,16 +221,33 @@ public static QueryMetadataInterface exampleSalesforce() {
Mockito.verify(sfc).retrieve("Account.id, Account.AccountName", "Account", Arrays.asList("bar"));
}
- @Test public void testDateTimeFormating() throws Exception {
+ @BeforeClass static public void oneTimeSetup() {
TimeZone.setDefault(TimeZone.getTimeZone("GMT-06:00"));
- try {
- Select command = (Select)translationUtility.parseCommand("select name from contacts where initialcontact = {ts'2003-03-11 11:42:10.5'}"); //$NON-NLS-1$
- SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
- visitor.visit(command);
- assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.InitialContact = 2003-03-11T11:42:10.500-06:00", visitor.getQuery().toString().trim()); //$NON-NLS-1$
- } finally {
- TimeZone.setDefault(null);
- }
+ }
+
+ @AfterClass static public void oneTimeTearDown() {
+ TimeZone.setDefault(null);
+ }
+
+ @Test public void testDateTimeFormating() throws Exception {
+ Select command = (Select)translationUtility.parseCommand("select name from contacts where initialcontact = {ts'2003-03-11 11:42:10.5'}"); //$NON-NLS-1$
+ SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.InitialContact = 2003-03-11T11:42:10.500-06:00", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ }
+
+ @Test public void testDateTimeFormating1() throws Exception {
+ Select command = (Select)translationUtility.parseCommand("select name from contacts where initialcontact in ({ts'2003-03-11 11:42:10.506'}, {ts'2003-03-11 11:42:10.8088'})"); //$NON-NLS-1$
+ SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.InitialContact IN(2003-03-11T11:42:10.506-06:00,2003-03-11T11:42:10.80-06:00)", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ }
+
+ @Test public void testTimeFormatting() throws Exception {
+ Select command = (Select)translationUtility.parseCommand("select name from contacts where lasttime = {t'11:42:10'}"); //$NON-NLS-1$
+ SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.LastTime = 11:42:10.000-06:00", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
}
View
2  console/src/main/resources/META-INF/rhq-plugin.xml
@@ -394,7 +394,7 @@
<c:simple-property name="JdbcSocketConfiguration.enabled" displayName="Enable"
description="Enable Socket based JDBC access" required="false" readOnly="false" />
<c:simple-property name="JdbcSocketConfiguration.hostName" displayName="Host Name"
- description="Host Name" required="false" readOnly="false" />
+ description="Host Name" required="false" readOnly="true" />
<c:simple-property name="JdbcSocketConfiguration.portNumber" displayName="Port Number"
description="Port Number" required="false" readOnly="false" />
<c:simple-property name="JdbcSocketConfiguration.sslEnabled" displayName="SSL Enabled"
View
15 engine/src/main/java/org/teiid/common/buffer/impl/BufferFrontedFileStoreCache.java
@@ -193,7 +193,7 @@ private int getOrUpdateDataBlockIndex(int index, int value, Mode mode) {
position = BYTES_PER_BLOCK_ADDRESS*index;
}
if (mode == Mode.ALLOCATE) {
- dataBlock = nextBlock(true);
+ dataBlock = nextBlock(info, true);
info.putInt(position, dataBlock);
if (mode == Mode.ALLOCATE && position + BYTES_PER_BLOCK_ADDRESS < info.limit()) {
//maintain the invariant that the next pointer is empty
@@ -212,7 +212,7 @@ private ByteBuffer updateIndirectBlockInfo(ByteBuffer buf, int index, int positi
int sib_index = buf.getInt(position);
if (index == cutOff) {
if (mode == Mode.ALLOCATE) {
- sib_index = nextBlock(false);
+ sib_index = nextBlock(buf, false);
buf.putInt(position, sib_index);
} else if (mode == Mode.UPDATE && value == EMPTY_ADDRESS) {
freeDataBlock(sib_index);
@@ -225,9 +225,12 @@ private ByteBuffer updateIndirectBlockInfo(ByteBuffer buf, int index, int positi
/**
* Get the next dataBlock. When the memory buffer is full we have some
* book keeping to do.
+ * @param reading
* @return
*/
- private int nextBlock(boolean data) {
+ private int nextBlock(ByteBuffer reading, boolean data) {
+ int limit = reading.limit();
+ int position = reading.position();
int next = EMPTY_ADDRESS;
memoryEvictionLock.readLock().lock();
boolean readLocked = true;
@@ -245,6 +248,12 @@ private int nextBlock(boolean data) {
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_BUFFER_MGR, MessageLevel.TRACE)) {
LogManager.logTrace(LogConstants.CTX_BUFFER_MGR, "Allocating", data?"data":"index", "block", next, "to", gid, oid); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
+ //restore the reading buffer
+ if (reading.limit() != limit) {
+ reading.rewind();
+ reading.limit(limit);
+ reading.position(position);
+ }
return next;
}
View
2  engine/src/main/java/org/teiid/dqp/internal/datamgr/ConnectorManager.java
@@ -232,7 +232,7 @@ void logSRCCommand(AtomicRequestMessage qr, ExecutionContext context, Event cmdS
* Get the <code>Translator</code> object managed by this manager.
* @return the <code>ExecutionFactory</code>.
*/
- protected ExecutionFactory<Object, Object> getExecutionFactory() {
+ public ExecutionFactory<Object, Object> getExecutionFactory() {
return this.executionFactory;
}
View
53 engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
@@ -109,6 +109,11 @@
private PlanHints hints = new PlanHints();
private Option option;
private SourceHint sourceHint;
+ private static ThreadLocal<Boolean> planningLoop = new ThreadLocal<Boolean>() {
+ protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
public ProcessorPlan optimize(
Command command)
@@ -264,18 +269,23 @@ private void connectSubqueryContainers(PlanNode plan) throws QueryPlannerExcepti
CorrelatedReferenceCollectorVisitor.collectReferences(subCommand, localGroupSymbols, correlatedReferences);
ProcessorPlan procPlan = QueryOptimizer.optimizePlan(subCommand, metadata, idGenerator, capFinder, analysisRecord, context);
container.getCommand().setProcessorPlan(procPlan);
- if (!correlatedReferences.isEmpty()) {
- SymbolMap map = new SymbolMap();
- for (Reference reference : correlatedReferences) {
- map.addMapping(reference.getExpression(), reference.getExpression());
- }
- container.getCommand().setCorrelatedReferences(map);
- }
+ setCorrelatedReferences(container, correlatedReferences);
}
node.addGroups(GroupsUsedByElementsVisitor.getGroups(node.getCorrelatedReferenceElements()));
}
}
+ private void setCorrelatedReferences(SubqueryContainer<?> container,
+ List<Reference> correlatedReferences) {
+ if (!correlatedReferences.isEmpty()) {
+ SymbolMap map = new SymbolMap();
+ for (Reference reference : correlatedReferences) {
+ map.addMapping(reference.getExpression(), reference.getExpression());
+ }
+ container.getCommand().setCorrelatedReferences(map);
+ }
+ }
+
private static Set<GroupSymbol> getGroupSymbols(PlanNode plan) {
Set<GroupSymbol> groupSymbols = new HashSet<GroupSymbol>();
for (PlanNode source : NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE)) {
@@ -538,6 +548,14 @@ private boolean addNestedProcedure(PlanNode sourceNode,
context.accessedPlanningObject(sp.getProcedureID());
}
}
+ for (SubqueryContainer<?> subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container)) {
+ if (subqueryContainer.getCommand().getCorrelatedReferences() != null) {
+ continue;
+ }
+ List<Reference> correlatedReferences = new ArrayList<Reference>();
+ CorrelatedReferenceCollectorVisitor.collectReferences(subqueryContainer.getCommand(), Arrays.asList(container.getGroup()), correlatedReferences);
+ setCorrelatedReferences(subqueryContainer, correlatedReferences);
+ }
String cacheString = "transformation/" + container.getClass().getSimpleName().toUpperCase(); //$NON-NLS-1$
Command c = (Command)metadata.getFromMetadataCache(metadataId, cacheString);
if (c == null) {
@@ -588,13 +606,22 @@ private boolean addNestedProcedure(PlanNode sourceNode,
throw new QueryPlannerException(QueryPlugin.Util.getString("RelationalPlanner.nonpushdown_command", container)); //$NON-NLS-1$
}
- //treat this as an update procedure
- if (container instanceof Update) {
- c = QueryRewriter.createUpdateProcedure((Update)container, metadata, context);
- } else {
- c = QueryRewriter.createDeleteProcedure((Delete)container, metadata, context);
+ try {
+ if (planningLoop.get()) {
+ throw new QueryPlannerException(QueryPlugin.Util.getString("RelationalPlanner.nonpushdown_expression", container)); //$NON-NLS-1$
+ }
+ planningLoop.set(Boolean.TRUE);
+
+ //treat this as an update procedure
+ if (container instanceof Update) {
+ c = QueryRewriter.createUpdateProcedure((Update)container, metadata, context);
+ } else {
+ c = QueryRewriter.createDeleteProcedure((Delete)container, metadata, context);
+ }
+ addNestedCommand(sourceNode, container.getGroup(), container, c, false);
+ } finally {
+ planningLoop.set(Boolean.FALSE);
}
- addNestedCommand(sourceNode, container.getGroup(), container, c, false);
return false;
}
View
2  engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
@@ -800,7 +800,7 @@ private Criteria rewriteCriteria(Criteria criteria) throws TeiidComponentExcepti
} else if (criteria instanceof DependentSetCriteria) {
criteria = rewriteDependentSetCriteria((DependentSetCriteria)criteria);
} else if (criteria instanceof ExpressionCriteria) {
- return new CompareCriteria(((ExpressionCriteria) criteria).getExpression(), CompareCriteria.EQ, new Constant(Boolean.TRUE));
+ return rewriteCriteria(new CompareCriteria(((ExpressionCriteria) criteria).getExpression(), CompareCriteria.EQ, new Constant(Boolean.TRUE)));
}
return evaluateCriteria(criteria);
View
1  engine/src/main/java/org/teiid/query/sql/lang/Command.java
@@ -344,7 +344,6 @@ public String toString() {
protected boolean sameOptionAndHint(Command cmd) {
return EquivalenceUtil.areEqual(this.cacheHint, cmd.cacheHint) &&
- EquivalenceUtil.areEqual(this.cacheHint, cmd.cacheHint) &&
EquivalenceUtil.areEqual(this.option, cmd.option);
}
View
1  engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
@@ -1374,6 +1374,7 @@ public void visit( CommandStatement obj ) {
}
public void visit( CreateProcedureCommand obj ) {
+ addCacheHint(obj.getCacheHint());
append(CREATE);
append(SPACE);
append(VIRTUAL);
View
1  engine/src/main/resources/org/teiid/query/i18n.properties
@@ -920,6 +920,7 @@ failed_to_unwrap_connection=Failed to unwrap the source connection.
connection_factory_not_found=Failed to find the Connection Factory with JNDI name {0}. Please check the name or deploy the Connection Factory with specified name.
RelationalPlanner.nonpushdown_command=Source UPDATE or DELETE command "{0}" contains non-pushdown constructs and no compensating action can be taken as the table lacks a unique key or the source does not support equality predicates.
+RelationalPlanner.nonpushdown_expression=Source UPDATE or DELETE command "{0}" contains non-pushdown constructs that cannot be simplified into a compensating action.
Translate.error=Cannot translate criteria "{0}", it is not matched by selector "{1}"
View
2  engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java
@@ -46,7 +46,7 @@
static ConnectorManager getConnectorManager() throws Exception {
final FakeConnector c = new FakeConnector();
ConnectorManager cm = new ConnectorManager("FakeConnector","FakeConnector") { //$NON-NLS-1$ //$NON-NLS-2$
- protected ExecutionFactory getExecutionFactory() {
+ public ExecutionFactory getExecutionFactory() {
return c;
}
protected Object getConnectionFactory(){
View
29 engine/src/test/java/org/teiid/query/parser/TestOptionsAndHints.java
@@ -30,26 +30,10 @@
import org.junit.Test;
import org.teiid.api.exception.query.QueryParserException;
-import org.teiid.query.sql.lang.AbstractCompareCriteria;
-import org.teiid.query.sql.lang.CacheHint;
-import org.teiid.query.sql.lang.CompareCriteria;
-import org.teiid.query.sql.lang.Criteria;
-import org.teiid.query.sql.lang.Delete;
-import org.teiid.query.sql.lang.From;
-import org.teiid.query.sql.lang.FromClause;
-import org.teiid.query.sql.lang.Insert;
-import org.teiid.query.sql.lang.JoinPredicate;
-import org.teiid.query.sql.lang.JoinType;
-import org.teiid.query.sql.lang.Option;
-import org.teiid.query.sql.lang.Query;
-import org.teiid.query.sql.lang.SPParameter;
-import org.teiid.query.sql.lang.Select;
-import org.teiid.query.sql.lang.SetQuery;
-import org.teiid.query.sql.lang.StoredProcedure;
-import org.teiid.query.sql.lang.SubqueryFromClause;
-import org.teiid.query.sql.lang.UnaryFromClause;
-import org.teiid.query.sql.lang.Update;
+import org.teiid.query.sql.lang.*;
import org.teiid.query.sql.lang.SetQuery.Operation;
+import org.teiid.query.sql.proc.Block;
+import org.teiid.query.sql.proc.CreateProcedureCommand;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.Function;
@@ -962,6 +946,13 @@
TestParser.helpTest(sql, "/*+ cache */ SELECT * FROM t1", query); //$NON-NLS-1$
}
+ @Test public void testCacheProc() {
+ String sql = "/*+ cache */ CREATE VIRTUAL PROCEDURE BEGIN END"; //$NON-NLS-1$
+ CreateProcedureCommand command = new CreateProcedureCommand(new Block());
+ command.setCacheHint(new CacheHint());
+ TestParser.helpTest(sql, "/*+ cache */ CREATE VIRTUAL PROCEDURE\nBEGIN\nEND", command); //$NON-NLS-1$
+ }
+
@Test public void testCacheScope() {
String sql = "/*+ cache(pref_mem scope:session) */ SELECT * FROM t1"; //$NON-NLS-1$
View
12 engine/src/test/java/org/teiid/query/processor/TestProcessor.java
@@ -32,6 +32,7 @@
import java.util.*;
import org.junit.Test;
+import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.client.metadata.ParameterInfo;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
@@ -7543,6 +7544,17 @@ private void sampleDataBQT2a(FakeDataManager dataMgr) throws Exception {
helpProcess(plan, dataManager, expected);
}
+ @Test(expected=QueryPlannerException.class) public void testUpdateCompensationNotPossible() throws Exception {
+ String sql = "update pm1.g1 set e4 = (select e4 from pm1.g2 where pm1.g2.e2 = pm1.g1.e2) where e1 = 'a'"; //$NON-NLS-1$
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+
+ BasicSourceCapabilities caps = getTypicalCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_SUBQUERIES_SCALAR, false);
+ helpGetPlan(helpParse(sql), RealMetadataFactory.example4(), new DefaultCapabilitiesFinder(caps), createCommandContext());
+ }
+
@Test public void testDupSelect() throws Exception {
String sql = "select e1, e1 from pm1.g1";
View
21 engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
@@ -124,6 +124,27 @@
assertEquals("UPDATE pm1.g1 SET e2 = 5 WHERE e2 = 2", dm.getQueries().get(0));
}
+ @Test public void testUpdateWithChanging() throws Exception {
+ TransformationMetadata metadata = TestUpdateValidator.example1();
+ TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, GX);
+ Table t = metadata.getMetadataStore().getSchemas().get(VM1).getTables().get(GX);
+ t.setDeletePlan("");
+ t.setUpdatePlan("FOR EACH ROW BEGIN update pm1.g1 set e2 = case when changing.y then new.y end where e2 = old.y; END");
+ t.setInsertPlan("");
+
+ String sql = "update gx set y = 5";
+
+ FakeDataManager dm = new FakeDataManager();
+ FakeDataStore.addTable("pm1.g1", dm, metadata);
+
+ CommandContext context = createCommandContext();
+ BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+ ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata), metadata, new DefaultCapabilitiesFinder(caps), context);
+ List<?>[] expected = new List[] {Arrays.asList(1)};
+ helpProcess(plan, context, dm, expected);
+ assertEquals("UPDATE pm1.g1 SET e2 = 5 WHERE e2 = 2", dm.getQueries().get(0));
+ }
+
@Test public void testUpdateWithNonConstant() throws Exception {
TransformationMetadata metadata = TestUpdateValidator.example1();
TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, GX);
View
1  jboss-integration/src/main/java/org/teiid/jboss/TeiidAdd.java
@@ -208,6 +208,7 @@ public TranslatorRepository getValue() throws IllegalStateException, IllegalArgu
// VDB Status manager
final VDBStatusCheckerExecutorService statusChecker = new VDBStatusCheckerExecutorService(vdbRepository);
+ statusChecker.setTranslatorRepository(translatorRepo);
ValueService<VDBStatusChecker> statusService = new ValueService<VDBStatusChecker>(new org.jboss.msc.value.Value<VDBStatusChecker>() {
@Override
public VDBStatusChecker getValue() throws IllegalStateException, IllegalArgumentException {
View
13 jboss-integration/src/main/java/org/teiid/jboss/TeiidOperationHandler.java
@@ -21,14 +21,7 @@
*/
package org.teiid.jboss;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ALLOWED;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DEFAULT;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_ONLY;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REPLY_PROPERTIES;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUEST_PROPERTIES;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUIRED;
-import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.*;
import java.io.IOException;
import java.math.BigDecimal;
@@ -1190,6 +1183,10 @@ protected void executeOperation(OperationContext context, VDBMetaData vdb, Model
source.setTranslatorName(translatorName);
source.setConnectionJndiName(dsName);
save(vdb);
+ ServiceController<?> sc = context.getServiceRegistry(false).getRequiredService(TeiidServiceNames.VDB_STATUS_CHECKER);
+ VDBStatusChecker vsc = VDBStatusChecker.class.cast(sc.getValue());
+ // enforce the changes in the engine.
+ vsc.dataSourceReplaced(vdb.getName(), vdb.getVersion(), modelName, sourceName, translatorName, dsName);
} catch (AdminProcessingException e) {
throw new OperationFailedException(new ModelNode().set(e.getMessage()));
}
View
2  jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
@@ -96,7 +96,7 @@ public VDBService(VDBMetaData metadata) {
public void start(StartContext context) throws StartException {
ConnectorManagerRepository cmr = new ConnectorManagerRepository();
TranslatorRepository repo = new TranslatorRepository();
-
+ this.vdb.addAttchment(TranslatorRepository.class, repo);
// check if this is a VDB with index files, if there are then build the TransformationMetadata
UDFMetaData udf = this.vdb.getAttachment(UDFMetaData.class);
IndexMetadataFactory indexFactory = this.vdb.getAttachment(IndexMetadataFactory.class);
View
5 pom.xml
@@ -486,6 +486,11 @@
<version>${jbossas-version}</version>
</dependency>
<dependency>
+ <groupId>org.jgroups</groupId>
+ <artifactId>jgroups</artifactId>
+ <version>3.0.0.Final</version>
+ </dependency>
+ <dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-subsystem-test</artifactId>
<version>${jbossas-version}</version>
View
73 runtime/src/main/java/org/teiid/deployers/VDBStatusChecker.java
@@ -23,24 +23,27 @@
import java.util.LinkedList;
import java.util.concurrent.Executor;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import org.teiid.adminapi.AdminProcessingException;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.VDB;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.adminapi.impl.VDBTranslatorMetaData;
+import org.teiid.core.TeiidException;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
+import org.teiid.dqp.internal.datamgr.TranslatorRepository;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.runtime.RuntimePlugin;
+import org.teiid.translator.ExecutionFactory;
-public class VDBStatusChecker {
+public abstract class VDBStatusChecker {
private static final String JAVA_CONTEXT = "java:/"; //$NON-NLS-1$
private VDBRepository vdbRepository;
+ private TranslatorRepository translatorRepository;
public VDBStatusChecker(VDBRepository vdbRepository) {
this.vdbRepository = vdbRepository;
@@ -67,6 +70,63 @@ public void dataSourceRemoved(String dataSourceName) {
}
resourceremoved(dataSourceName, false);
}
+
+ public void dataSourceReplaced(String vdbName, int vdbVersion,
+ String modelName, String sourceName, String translatorName,
+ String dsName) throws AdminProcessingException {
+ if (dsName.startsWith(JAVA_CONTEXT)) {
+ dsName = dsName.substring(5);
+ }
+
+ VDBMetaData vdb = this.vdbRepository.getVDB(vdbName, vdbVersion);
+ ModelMetaData model = vdb.getModel(modelName);
+
+ synchronized (vdb) {
+ ConnectorManagerRepository cmr = vdb.getAttachment(ConnectorManagerRepository.class);
+ ConnectorManager cm = cmr.getConnectorManager(sourceName);
+ ExecutionFactory<Object, Object> ef = cm.getExecutionFactory();
+
+ boolean dsReplaced = false;
+ if (!cm.getConnectionName().equals(dsName)){
+ vdb.setStatus(VDB.Status.INACTIVE);
+ String msg = RuntimePlugin.Util.getString("datasource_replaced", vdb.getName(), vdb.getVersion(), model.getSourceTranslatorName(sourceName), dsName); //$NON-NLS-1$
+ model.addError(ModelMetaData.ValidationError.Severity.ERROR.name(), msg);
+ cm = new ConnectorManager(translatorName, dsName);
+ cm.setExecutionFactory(ef);
+ cm.setModelName(modelName);
+ cmr.addConnectorManager(sourceName, cm);
+ dsReplaced = true;
+ }
+
+ if (!cm.getTranslatorName().equals(translatorName)) {
+ try {
+ TranslatorRepository repo = vdb.getAttachment(TranslatorRepository.class);
+ VDBTranslatorMetaData t = null;
+ if (repo != null) {
+ t = repo.getTranslatorMetaData(translatorName);
+ }
+ if (t == null) {
+ t = this.translatorRepository.getTranslatorMetaData(translatorName);
+ }
+ if (t == null) {
+ throw new AdminProcessingException(RuntimePlugin.Util.getString("translator_not_found", vdb.getName(), vdb.getVersion(), translatorName)); //$NON-NLS-1$
+ }
+ ef = TranslatorUtil.buildExecutionFactory(t, Thread.currentThread().getContextClassLoader());
+ cm.setExecutionFactory(ef);
+ } catch (TeiidException e) {
+ throw new AdminProcessingException(e.getCause());
+ }
+ }
+
+ if (dsReplaced) {
+ resourceAdded(dsName, false);
+ }
+ }
+ }
+
+ public void setVDBRepository(VDBRepository repo) {
+ this.vdbRepository = repo;
+ }
public void resourceAdded(String resourceName, boolean translator) {
for (VDBMetaData vdb:this.vdbRepository.getVDBs()) {
@@ -172,8 +232,9 @@ private String getSourceName(String translatorName, ModelMetaData model, boolean
return null;
}
+ public abstract Executor getExecutor();
- public Executor getExecutor() {
- return new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
+ public void setTranslatorRepository(TranslatorRepository repo) {
+ this.translatorRepository = repo;
}
}
View
4 runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
@@ -201,7 +201,6 @@ public void logon(String databaseName, String user, NullTerminatedStringDataInpu
info.put("user", user); //$NON-NLS-1$
String password = null;
- String passthroughAuthentication = ""; //$NON-NLS-1$
if (authType.equals(AuthenticationType.CLEARTEXT)) {
password = data.readString();
}
@@ -210,7 +209,6 @@ else if (authType.equals(AuthenticationType.GSS)) {
LogonResult result = this.logon.neogitiateGssLogin(this.props, serviceToken, false);
serviceToken = (byte[])result.getProperty(ILogon.KRB5TOKEN);
if (Boolean.TRUE.equals(result.getProperty(ILogon.KRB5_ESTABLISHED))) {
- passthroughAuthentication = ";PassthroughAuthentication=true;authenticationType=KRB5"; //$NON-NLS-1$
info.put(ILogon.KRB5TOKEN, serviceToken);
}
else {
@@ -220,7 +218,7 @@ else if (authType.equals(AuthenticationType.GSS)) {
}
// this is local connection
- String url = "jdbc:teiid:"+databaseName+";ApplicationName=ODBC"+passthroughAuthentication; //$NON-NLS-1$ //$NON-NLS-2$
+ String url = "jdbc:teiid:"+databaseName+";ApplicationName=ODBC"; //$NON-NLS-1$ //$NON-NLS-2$
if (password != null) {
info.put("password", password); //$NON-NLS-1$
View
2  runtime/src/main/java/org/teiid/transport/SSLConfiguration.java
@@ -151,7 +151,7 @@ public void setEnabledCipherSuites(String enabledCipherSuites) {
this.enabledCipherSuites = enabledCipherSuites.split(","); //$NON-NLS-1$
}
- public String[] getEnabledCipherSuites() {
+ public String[] getEnabledCipherSuitesAsArray() {
return enabledCipherSuites;
}
}
View
1  runtime/src/main/resources/org/teiid/runtime/i18n.properties
@@ -70,6 +70,7 @@ vdb_not_found=VDB {0}.{1} not found deployed.
translator_not_found=For {0}.{1} VDB, Translator "{2}" not found.
recursive_delegation=For {0}.{1} VDB, recursive delegation {2} found.
datasource_not_found=For {0}.{1} VDB, Data Source "{2}" not found.
+datasource_replaced=For {0}.{1} VDB, Data Source "{2}" replaced with "{3}"
vdb_activated={0}.{1} status has been changed to active
vdb_inactivated={0}.{1} status has been changed to inactive. Check the required translators and data sources!
translator_added=Teiid translator "{0}" has been added.
View
2  runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
@@ -78,7 +78,7 @@ private static ConnectorManager getConnectorManager(String modelName, String tra
Mockito.stub(ef.getPushDownFunctions()).toReturn(funcs);
ConnectorManager cm = new ConnectorManager(translatorName,connectionName) {
- protected ExecutionFactory getExecutionFactory() {
+ public ExecutionFactory getExecutionFactory() {
return ef;
}
};
View
2  runtime/src/test/java/org/teiid/transport/TestCommSockets.java
@@ -259,7 +259,7 @@ public void assertIdentity(SessionToken checkSession)
@Test public void testEnableCipherSuites() throws Exception {
SSLConfiguration config = new SSLConfiguration();
config.setEnabledCipherSuites("x,y,z");
- assertArrayEquals(new String[] {"x","y","z"}, config.getEnabledCipherSuites());
+ assertArrayEquals(new String[] {"x","y","z"}, config.getEnabledCipherSuitesAsArray());
}
}
View
2  test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
@@ -103,7 +103,7 @@ public static int blocking() throws InterruptedException {
public ConnectorManager getConnectorManager(String connectorName) {
return new ConnectorManager(connectorName, connectorName) {
@Override
- protected ExecutionFactory<Object, Object> getExecutionFactory() {
+ public ExecutionFactory<Object, Object> getExecutionFactory() {
return new ExecutionFactory<Object, Object>() {
@Override
public Execution createExecution(Command command,
Please sign in to comment.
Something went wrong with that request. Please try again.