teiid SVN: r3539 - trunk/documentation/admin-guide/src/main/docbook/en-US/content.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-10-06 17:06:06 -0400 (Thu, 06 Oct 2011)
New Revision: 3539
Modified:
trunk/documentation/admin-guide/src/main/docbook/en-US/content/security.xml
Log:
TEIID-1772: adding ability custom configure the cipher suites for ssl connection
Modified: trunk/documentation/admin-guide/src/main/docbook/en-US/content/security.xml
===================================================================
--- trunk/documentation/admin-guide/src/main/docbook/en-US/content/security.xml 2011-10-06 20:43:45 UTC (rev 3538)
+++ trunk/documentation/admin-guide/src/main/docbook/en-US/content/security.xml 2011-10-06 21:06:06 UTC (rev 3539)
@@ -367,6 +367,8 @@
<property name="truststorePassword">passwd</property>
<!-- 1-way, 2-way, anonymous -->
<property name="authenticationMode">1-way</property>
+ <!-- an optional property to constrain the cipher suites to be negotiated between server and client -->
+ <property name="enabledCipherSuites">SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA</property>
</bean>]]></programlisting>
</example>
<itemizedlist>
@@ -387,6 +389,7 @@
public key for the client. Depending upon how you created the keystore and truststores,
this may be same file as defined under "keystoreFilename" property.</para></listitem>
<listitem><para>truststorePassword - password for the truststore. </para></listitem>
+ <listitem><para>enabledCipherSuites - A comma separated list of cipher suites allowed for encryption between server and client</para></listitem>
</itemizedlist>
<section id="ssl_auth">
<title>SSL Authentication Modes</title>
@@ -408,8 +411,9 @@
</section>
<section id="encryption_strength">
<title>Encryption Strength</title>
- <para>Both anonymous SSL and login only encryption are configured to use 128 bit AES encryption.
- 1-way and 2-way SSL allow for cipher suite negotiation based upon the default cipher suites supported by the respective Java platforms of the client and server.
+ <para>Both anonymous SSL and login only encryption are configured to use 128 bit AES encryption by default. By default,
+ 1-way and 2-way SSL allow for cipher suite negotiation based upon the default cipher suites supported by the respective Java platforms of the client and server.
+ User can restrict the cipher suites used for encryption by specifying the <emphasis>enabledCipherSuites</emphasis> property above in ssl configuration.
</para>
</section>
</section>
13 years, 2 months
teiid SVN: r3538 - in trunk: runtime/src/main/java/org/teiid/transport and 1 other directory.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-10-06 16:43:45 -0400 (Thu, 06 Oct 2011)
New Revision: 3538
Modified:
trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
trunk/runtime/src/main/java/org/teiid/transport/SSLConfiguration.java
Log:
TEIID-1772: adding ability custom configure the cipher suites for ssl connection
Modified: trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
===================================================================
--- trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-10-06 19:40:43 UTC (rev 3537)
+++ trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-10-06 20:43:45 UTC (rev 3538)
@@ -231,6 +231,9 @@
<property name="truststorePassword">passwd</property>
<!-- 1-way, 2-way, anonymous -->
<property name="authenticationMode">anonymous</property>
+ <!-- uncomment for enforcing the minimum 128 bit encryption, edit or supply only supported cipher suites from JVM
+ <property name="enabledCipherSuites">SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_KRB5_WITH_RC4_128_MD5,TLS_KRB5_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_KRB5_WITH_3DES_EDE_CBC_MD5,TLS_KRB5_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA</property>
+ -->
</bean>
<!-- JDBC Socket connection properties (SSL see below) -->
Modified: trunk/runtime/src/main/java/org/teiid/transport/SSLConfiguration.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/SSLConfiguration.java 2011-10-06 19:40:43 UTC (rev 3537)
+++ trunk/runtime/src/main/java/org/teiid/transport/SSLConfiguration.java 2011-10-06 20:43:45 UTC (rev 3538)
@@ -24,7 +24,9 @@
import java.io.IOException;
import java.security.GeneralSecurityException;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.StringTokenizer;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@@ -59,8 +61,10 @@
private String trustStoreFileName;
private String trustStorePassword = ""; //$NON-NLS-1$
private String authenticationMode = ONEWAY;
+ private String[] enabledCipherSuites;
- public SSLEngine getServerSSLEngine() throws IOException, GeneralSecurityException {
+
+ public SSLEngine getServerSSLEngine() throws IOException, GeneralSecurityException {
if (!isSslEnabled()) {
return null;
}
@@ -86,10 +90,13 @@
if (!(Arrays.asList(result.getSupportedCipherSuites()).contains(SocketUtil.ANON_CIPHER_SUITE))) {
throw new GeneralSecurityException(RuntimePlugin.Util.getString("SSLConfiguration.no_anonymous")); //$NON-NLS-1$
}
- result.setEnabledCipherSuites(new String[] {
- SocketUtil.ANON_CIPHER_SUITE
- });
- }
+ result.setEnabledCipherSuites(this.enabledCipherSuites == null?new String[] {SocketUtil.ANON_CIPHER_SUITE}:this.enabledCipherSuites);
+ } else {
+ if (this.enabledCipherSuites != null) {
+ result.setEnabledCipherSuites(this.enabledCipherSuites);
+ }
+ }
+
result.setNeedClientAuth(TWOWAY.equals(authenticationMode));
return result;
}
@@ -142,4 +149,15 @@
this.authenticationMode = value;
}
+ public void setEnabledCipherSuites(String enabledCipherSuites) {
+ ArrayList<String> ciphers = new ArrayList<String>();
+ StringTokenizer st = new StringTokenizer(enabledCipherSuites);
+ while(st.hasMoreTokens()) {
+ ciphers.add(st.nextToken().trim());
+ }
+
+ if (!ciphers.isEmpty()) {
+ this.enabledCipherSuites = ciphers.toArray(new String[ciphers.size()]);
+ }
+ }
}
13 years, 2 months
teiid SVN: r3537 - branches/7.4.x/documentation/reference/src/main/docbook/en-US/content.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-06 15:40:43 -0400 (Thu, 06 Oct 2011)
New Revision: 3537
Modified:
branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml
Log:
TEIID-1760 adding access to the reference
Modified: branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-10-06 17:19:47 UTC (rev 3536)
+++ branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-10-06 19:40:43 UTC (rev 3537)
@@ -234,6 +234,11 @@
</listitem>
<listitem>
<para>
+ <emphasis>access</emphasis> - for use with Microsoft Access 2003 or later.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<emphasis>db2</emphasis> - for use with DB2 8 or later.
</para>
</listitem>
13 years, 2 months
teiid SVN: r3536 - in branches/7.4.x/connectors/translator-jdbc/src: test/java/org/teiid/translator/jdbc/ingres and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-06 13:19:47 -0400 (Thu, 06 Oct 2011)
New Revision: 3536
Added:
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/ingres/TestIngresExecutionFactory.java
Modified:
branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/IngresExecutionFactory.java
branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/LocateFunctionModifier.java
Log:
TEIID-1773 fixing the locate modifier
Modified: branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/IngresExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/IngresExecutionFactory.java 2011-10-06 03:13:25 UTC (rev 3535)
+++ branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/IngresExecutionFactory.java 2011-10-06 17:19:47 UTC (rev 3536)
@@ -76,7 +76,7 @@
registerFunctionModifier(SourceSystemFunctions.RAND, new AliasModifier("random")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("uppercase")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new AliasModifier("day")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory()));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier());
addPushDownFunction(INGRES, "bit_add", INTEGER, INTEGER, INTEGER); //$NON-NLS-1$
addPushDownFunction(INGRES, "bit_length", INTEGER, INTEGER); //$NON-NLS-1$
Modified: branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/LocateFunctionModifier.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/LocateFunctionModifier.java 2011-10-06 03:13:25 UTC (rev 3535)
+++ branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/ingres/LocateFunctionModifier.java 2011-10-06 17:19:47 UTC (rev 3536)
@@ -21,28 +21,24 @@
*/
package org.teiid.translator.jdbc.ingres;
-import java.util.Arrays;
import java.util.List;
import org.teiid.language.Expression;
import org.teiid.language.Function;
-import org.teiid.language.LanguageFactory;
-import org.teiid.translator.TypeFacility;
import org.teiid.translator.jdbc.FunctionModifier;
public class LocateFunctionModifier extends FunctionModifier {
- private LanguageFactory languageFactory;
-
- public LocateFunctionModifier(LanguageFactory languageFactory) {
- this.languageFactory = languageFactory;
+ public LocateFunctionModifier() {
}
+
@Override
public List<?> translate(Function function) {
Expression a = function.getParameters().get(0);
Expression b = function.getParameters().get(1);
-
- return Arrays.asList(languageFactory.createFunction("locate", new Expression[] {b, a}, TypeFacility.RUNTIME_TYPES.INTEGER)); //$NON-NLS-1$
+ function.getParameters().set(0, b);
+ function.getParameters().set(1, a);
+ return null;
}
}
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/ingres/TestIngresExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/ingres/TestIngresExecutionFactory.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/ingres/TestIngresExecutionFactory.java 2011-10-06 17:19:47 UTC (rev 3536)
@@ -0,0 +1,47 @@
+/*
+ * 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.translator.jdbc.ingres;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.TranslationHelper;
+
+public class TestIngresExecutionFactory {
+
+ private static IngresExecutionFactory TRANSLATOR;
+
+ @BeforeClass
+ public static void setUp() throws TranslatorException {
+ TRANSLATOR = new IngresExecutionFactory();
+ TRANSLATOR.start();
+ }
+
+ @Test public void testLocate() throws Exception {
+ String input = "SELECT INTKEY FROM BQT1.SmallA WHERE LOCATE(1, INTKEY) = 1 ORDER BY INTKEY"; //$NON-NLS-1$
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE locate(cast(SmallA.IntKey AS varchar(4000)), '1') = 1 ORDER BY SmallA.IntKey"; //$NON-NLS-1$
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
+ }
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/ingres/TestIngresExecutionFactory.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
13 years, 2 months
teiid SVN: r3535 - in branches/7.4.x: engine/src/test/java/org/teiid/dqp/internal/process and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-05 23:13:25 -0400 (Wed, 05 Oct 2011)
New Revision: 3535
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java
branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestMetaDataProcessor.java
branches/7.4.x/runtime/src/main/java/org/teiid/transport/SocketClientInstance.java
Log:
TEIID-1771 adding a fix to ensure backwards compatibility
Modified: branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java 2011-10-06 02:25:05 UTC (rev 3534)
+++ branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java 2011-10-06 03:13:25 UTC (rev 3535)
@@ -29,7 +29,9 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@@ -48,6 +50,39 @@
private static final long serialVersionUID = -6389893410233192977L;
+ public enum Version {
+ SEVEN_1("7.1"), //$NON-NLS-1$
+ SEVEN_2("7.2"), //$NON-NLS-1$
+ SEVEN_3("7.3"), //$NON-NLS-1$
+ SEVEN_4("7.4"); //$NON-NLS-1$
+
+ private String string;
+
+ private Version(String string) {
+ this.string = string;
+ }
+
+ @Override
+ public String toString() {
+ return string;
+ }
+
+ private static TreeMap<String, Version> versionMap = new TreeMap<String, Version>();
+ static {
+ for (Version v : Version.values()) {
+ versionMap.put(v.toString(), v);
+ }
+ }
+
+ public static Version getVersion(String version) {
+ Map.Entry<String, Version> v = versionMap.floorEntry(version);
+ if (v == null) {
+ return SEVEN_1;
+ }
+ return v.getValue();
+ }
+ }
+
private static ThreadLocal<DQPWorkContext> CONTEXTS = new ThreadLocal<DQPWorkContext>() {
protected DQPWorkContext initialValue() {
return new DQPWorkContext();
@@ -72,6 +107,7 @@
private SecurityHelper securityHelper;
private HashMap<String, DataPolicy> policies;
private boolean useCallingThread;
+ private Version clientVersion = Version.SEVEN_4;
public DQPWorkContext() {
}
@@ -257,5 +293,13 @@
}
}
return roles;
- }
+ }
+
+ public Version getClientVersion() {
+ return clientVersion;
+ }
+
+ public void setClientVersion(Version clientVersion) {
+ this.clientVersion = clientVersion;
+ }
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java 2011-10-06 02:25:05 UTC (rev 3534)
+++ branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java 2011-10-06 03:13:25 UTC (rev 3535)
@@ -39,6 +39,7 @@
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.XMLType;
import org.teiid.dqp.internal.process.DQPCore.ClientState;
+import org.teiid.dqp.internal.process.DQPWorkContext.Version;
import org.teiid.dqp.internal.process.SessionAwareCache.CacheID;
import org.teiid.dqp.internal.process.multisource.MultiSourceMetadataWrapper;
import org.teiid.dqp.message.RequestID;
@@ -77,6 +78,8 @@
private int vdbVersion;
private RequestID requestID;
+ private boolean labelAsName;
+
public MetaDataProcessor(DQPCore requestManager, SessionAwareCache<PreparedPlan> planCache, String vdbName, int vdbVersion) {
this.requestManager = requestManager;
this.planCache = planCache;
@@ -97,6 +100,7 @@
this.requestID = requestId;
this.metadata = workContext.getVDB().getAttachment(QueryMetadataInterface.class);
+ this.labelAsName = workContext.getClientVersion().compareTo(Version.SEVEN_3) <= 0;
// If multi-source, use the multi-source wrapper as well
Set<String> multiModels = workContext.getVDB().getMultiSourceModelNames();
@@ -243,7 +247,7 @@
Class<?> type = symbol.getType();
column.put(ResultsMetadataConstants.DATA_TYPE, DataTypeManager.getDataTypeName(type));
column.put(ResultsMetadataConstants.ELEMENT_LABEL, label);
- column.put(ResultsMetadataConstants.ELEMENT_NAME, metadata.getName(elementID));
+ column.put(ResultsMetadataConstants.ELEMENT_NAME, labelAsName?label:metadata.getName(elementID));
GroupSymbol group = symbol.getGroupSymbol();
if(group == null || group.getMetadataID() == null) {
@@ -396,7 +400,7 @@
column.put(ResultsMetadataConstants.VIRTUAL_DATABASE_NAME, vdbName);
column.put(ResultsMetadataConstants.VIRTUAL_DATABASE_VERSION, vdbVersion);
column.put(ResultsMetadataConstants.GROUP_NAME, tableName);
- column.put(ResultsMetadataConstants.ELEMENT_NAME, columnName);
+ column.put(ResultsMetadataConstants.ELEMENT_NAME, labelAsName?columnLabel:columnName);
column.put(ResultsMetadataConstants.ELEMENT_LABEL, columnLabel);
column.put(ResultsMetadataConstants.AUTO_INCREMENTING, Boolean.FALSE);
column.put(ResultsMetadataConstants.CASE_SENSITIVE, Boolean.FALSE);
Modified: branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestMetaDataProcessor.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestMetaDataProcessor.java 2011-10-06 02:25:05 UTC (rev 3534)
+++ branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestMetaDataProcessor.java 2011-10-06 03:13:25 UTC (rev 3535)
@@ -28,6 +28,7 @@
import java.util.Map;
import java.util.Set;
+import org.junit.Before;
import org.junit.Test;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
@@ -36,6 +37,7 @@
import org.teiid.client.metadata.ResultsMetadataConstants;
import org.teiid.core.types.DataTypeManager;
import org.teiid.dqp.internal.datamgr.FakeTransactionService;
+import org.teiid.dqp.internal.process.DQPWorkContext.Version;
import org.teiid.dqp.message.RequestID;
import org.teiid.metadata.Column;
import org.teiid.metadata.MetadataStore;
@@ -54,6 +56,12 @@
*/
@SuppressWarnings({"nls", "unchecked"})
public class TestMetaDataProcessor {
+
+ private boolean asLegacyClient;
+
+ @Before public void setup() {
+ asLegacyClient = false;
+ }
public Map[] helpGetMetadata(String sql, QueryMetadataInterface metadata, VDBMetaData vdb) throws Exception {
// Prepare sql
@@ -66,6 +74,9 @@
requestMgr.setTransactionService(new FakeTransactionService());
DQPWorkContext workContext = RealMetadataFactory.buildWorkContext(metadata, vdb);
+ if (asLegacyClient) {
+ workContext.setClientVersion(Version.SEVEN_3);
+ }
// Initialize components
RequestID requestID = workContext.getRequestID(1);
@@ -81,7 +92,18 @@
Map[] metadata = helpGetMetadata("SELECT e1 FROM pm1.g1", RealMetadataFactory.example1Cached(), RealMetadataFactory.example1VDB()); //$NON-NLS-1$
assertNotNull(metadata);
assertEquals(1, metadata.length);
+ assertEquals("e1", metadata[0].get(ResultsMetadataConstants.ELEMENT_NAME)); //$NON-NLS-1$
+ assertEquals("e1", metadata[0].get(ResultsMetadataConstants.ELEMENT_LABEL)); //$NON-NLS-1$
}
+
+ @Test public void testLegacyClient() throws Exception {
+ asLegacyClient = true;
+ Map[] metadata = helpGetMetadata("SELECT e1 as e2 FROM pm1.g1", RealMetadataFactory.example1Cached(), RealMetadataFactory.example1VDB()); //$NON-NLS-1$
+ assertNotNull(metadata);
+ assertEquals(1, metadata.length);
+ assertEquals("e2", metadata[0].get(ResultsMetadataConstants.ELEMENT_NAME)); //$NON-NLS-1$
+ assertEquals("e2", metadata[0].get(ResultsMetadataConstants.ELEMENT_LABEL)); //$NON-NLS-1$
+ }
@Test public void testSimpleUpdate() throws Exception {
Map[] metadata = helpGetMetadata("INSERT INTO pm1.g1 (e1) VALUES ('x')", RealMetadataFactory.example1Cached(), RealMetadataFactory.example1VDB()); //$NON-NLS-1$
@@ -246,7 +268,7 @@
Table pm1g2 = RealMetadataFactory.createPhysicalGroup("g2", pm1); //$NON-NLS-1$
// Create physical elements
- List<Column> pm1g1e = RealMetadataFactory.createElements(pm1g1,
+ RealMetadataFactory.createElements(pm1g1,
new String[] { "e1"}, //$NON-NLS-1$
new String[] { DataTypeManager.DefaultDataTypes.SHORT});
Modified: branches/7.4.x/runtime/src/main/java/org/teiid/transport/SocketClientInstance.java
===================================================================
--- branches/7.4.x/runtime/src/main/java/org/teiid/transport/SocketClientInstance.java 2011-10-06 02:25:05 UTC (rev 3534)
+++ branches/7.4.x/runtime/src/main/java/org/teiid/transport/SocketClientInstance.java 2011-10-06 03:13:25 UTC (rev 3535)
@@ -33,6 +33,7 @@
import org.teiid.core.crypto.DhKeyGenerator;
import org.teiid.core.crypto.NullCryptor;
import org.teiid.dqp.internal.process.DQPWorkContext;
+import org.teiid.dqp.internal.process.DQPWorkContext.Version;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
@@ -125,6 +126,8 @@
}
private void receivedHahdshake(Handshake handshake) throws CommunicationException {
+ String clientVersion = handshake.getVersion();
+ this.workContext.setClientVersion(Version.getVersion(clientVersion));
if (usingEncryption) {
byte[] returnedPublicKey = handshake.getPublicKey();
13 years, 2 months
teiid SVN: r3534 - in trunk: runtime/src/main/java/org/teiid/odbc and 2 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-05 22:25:05 -0400 (Wed, 05 Oct 2011)
New Revision: 3534
Modified:
trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
Log:
TEIID-1758 fix for deallocate handling
Modified: trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java 2011-10-05 20:52:01 UTC (rev 3533)
+++ trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java 2011-10-06 02:25:05 UTC (rev 3534)
@@ -73,7 +73,7 @@
return result;
}
- String normalizeId(String s) {
+ public static String normalizeId(String s) {
if (s.indexOf('"') == -1) {
return s;
}
@@ -164,7 +164,7 @@
return validateName(id, true);
}
- String removeEscapeChars(String str, String tickChar) {
+ static String removeEscapeChars(String str, String tickChar) {
return StringUtil.replaceAll(str, tickChar + tickChar, tickChar);
}
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-10-05 20:52:01 UTC (rev 3533)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-10-06 02:25:05 UTC (rev 3534)
@@ -56,6 +56,7 @@
import org.teiid.logging.LogManager;
import org.teiid.net.TeiidURL.CONNECTION.AuthenticationType;
import org.teiid.odbc.PGUtil.PgColInfo;
+import org.teiid.query.parser.SQLParserUtil;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.transport.ODBCClientInstance;
import org.teiid.transport.PgFrontendProtocol.NullTerminatedStringDataInputStream;
@@ -71,11 +72,11 @@
private static Pattern pkPattern = Pattern.compile("select ta.attname, ia.attnum, ic.relname, n.nspname, tc.relname " +//$NON-NLS-1$
"from pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class tc, pg_catalog.pg_index i, " +//$NON-NLS-1$
- "pg_catalog.pg_namespace n, pg_catalog.pg_class ic where tc.relname = (E?(?:'[^']*')+) AND n.nspname = (E?(?:'[^']*')+).*" );//$NON-NLS-1$
+ "pg_catalog.pg_namespace n, pg_catalog.pg_class ic where tc.relname = (E?(?:'[^']*')+) AND n.nspname = (E?(?:'[^']*')+).*", Pattern.DOTALL|Pattern.CASE_INSENSITIVE);//$NON-NLS-1$
private static Pattern pkKeyPattern = Pattern.compile("select ta.attname, ia.attnum, ic.relname, n.nspname, NULL from " + //$NON-NLS-1$
"pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class ic, pg_catalog.pg_index i, " + //$NON-NLS-1$
- "pg_catalog.pg_namespace n where ic.relname = (E?(?:'[^']*')+) AND n.nspname = (E?(?:'[^']*')+) .*"); //$NON-NLS-1$
+ "pg_catalog.pg_namespace n where ic.relname = (E?(?:'[^']*')+) AND n.nspname = (E?(?:'[^']*')+) .*", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private Pattern fkPattern = Pattern.compile("select\\s+((?:'[^']*')+)::name as PKTABLE_CAT," + //$NON-NLS-1$
"\\s+n2.nspname as PKTABLE_SCHEM," + //$NON-NLS-1$
@@ -141,22 +142,21 @@
"\\s+left outer join pg_catalog.pg_constraint cn" + //$NON-NLS-1$
"\\s+on cn.conrelid = ref.confrelid" + //$NON-NLS-1$
"\\s+and cn.contype = 'p'\\)" + //$NON-NLS-1$
- "\\s+order by ref.oid, ref.i"); //$NON-NLS-1$
+ "\\s+order by ref.oid, ref.i", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
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$
+ "\\s*and pg_catalog.pg_get_expr\\(adbin, adrelid\\) \\s*like '%nextval\\(%'", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$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 fetchPattern = Pattern.compile("FETCH (\\d+) IN \"(\\w+)\".*", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern movePattern = Pattern.compile("MOVE (\\d+) IN \"(\\w+)\".*", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern closePattern = Pattern.compile("CLOSE \"(\\w+)\"", Pattern.DOTALL|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 static Pattern deallocatePattern = Pattern.compile("DEALLOCATE(?:\\s+PREPARE)?\\s+(.*)", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern releasePattern = Pattern.compile("RELEASE (\\w+\\d?_*)", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern savepointPattern = Pattern.compile("SAVEPOINT (\\w+\\d?_*)", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern rollbackPattern = Pattern.compile("ROLLBACK\\s*(to)*\\s*(\\w+\\d+_*)*", Pattern.DOTALL|Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-
private TeiidDriver driver;
private ODBCClientRemote client;
private Properties props;
@@ -551,11 +551,9 @@
if (sql == null) {
return null;
}
+ Matcher m = null;
// selects are coming with "select\t" so using a space after "select" does not always work
if (StringUtil.startsWithIgnoreCase(sql, "select")) { //$NON-NLS-1$
- modified = sql.replace('\n', ' ');
-
- Matcher m = null;
if ((m = pkPattern.matcher(modified)).matches()) {
return new StringBuffer("SELECT k.Name AS attname, convert(Position, short) AS attnum, TableName AS relname, SchemaName AS nspname, TableName AS relname") //$NON-NLS-1$
.append(" FROM SYS.KeyColumns k") //$NON-NLS-1$
@@ -606,19 +604,21 @@
else if (sql.equalsIgnoreCase("show max_identifier_length")){ //$NON-NLS-1$
return "select 63"; //$NON-NLS-1$
}
- else {
- Matcher m = setPattern.matcher(sql);
- if (m.matches()) {
- return "SET " + m.group(2) + " " + m.group(4); //$NON-NLS-1$ //$NON-NLS-2$
- }
- else if (modified.equalsIgnoreCase("BEGIN")) { //$NON-NLS-1$
- return "START TRANSACTION"; //$NON-NLS-1$
- }
- else if ((m = rollbackPattern.matcher(modified)).matches()) {
- return "ROLLBACK"; //$NON-NLS-1$
- }
+ else if ((m = setPattern.matcher(sql)).matches()) {
+ return "SET " + m.group(2) + " " + m.group(4); //$NON-NLS-1$ //$NON-NLS-2$
}
- modified = sql;
+ else if (modified.equalsIgnoreCase("BEGIN")) { //$NON-NLS-1$
+ return "START TRANSACTION"; //$NON-NLS-1$
+ }
+ else if ((m = rollbackPattern.matcher(modified)).matches()) {
+ return "ROLLBACK"; //$NON-NLS-1$
+ }
+ else if ((m = savepointPattern.matcher(sql)).matches()) {
+ return "SELECT 0"; //$NON-NLS-1$
+ }
+ else if ((m = releasePattern.matcher(sql)).matches()) {
+ return "SELECT 0"; //$NON-NLS-1$
+ }
//these are somewhat dangerous
modified = modified.replaceAll("::[A-Za-z0-9]*", " "); //$NON-NLS-1$ //$NON-NLS-2$
modified = modified.replaceAll("'pg_toast'", "'SYS'"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -933,16 +933,10 @@
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));
+ String plan_name = m.group(1);
+ plan_name = SQLParserUtil.normalizeId(plan_name);
+ closePreparedStatement(plan_name);
client.sendCommandComplete("DEALLOCATE", 0); //$NON-NLS-1$
results.getResultsReceiver().receiveResults(1);
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-10-05 20:52:01 UTC (rev 3533)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-10-06 02:25:05 UTC (rev 3534)
@@ -56,6 +56,7 @@
import org.teiid.client.util.ResultsFuture;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.ReflectionHelper;
+import org.teiid.core.util.StringUtil;
import org.teiid.jdbc.ResultSetImpl;
import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
@@ -420,33 +421,36 @@
@Override
public void sendCommandComplete(String sql, int updateCount) {
startMessage('C');
- sql = sql.trim().toUpperCase();
// TODO remove remarks at the beginning
String tag;
- if (sql.startsWith("INSERT")) {
+ if (StringUtil.startsWithIgnoreCase(sql, "INSERT")) {
tag = "INSERT 0 " + updateCount;
- } else if (sql.startsWith("DELETE")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "DELETE")) {
tag = "DELETE " + updateCount;
- } else if (sql.startsWith("UPDATE")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "UPDATE")) {
tag = "UPDATE " + updateCount;
- } else if (sql.startsWith("SELECT") || sql.startsWith("CALL")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "SELECT") || StringUtil.startsWithIgnoreCase(sql, "CALL")) {
tag = "SELECT";
- } else if (sql.startsWith("BEGIN") || sql.startsWith("START TRANSACTION")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "BEGIN") || StringUtil.startsWithIgnoreCase(sql, "START TRANSACTION")) {
tag = "BEGIN";
- } else if (sql.startsWith("COMMIT")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "COMMIT")) {
tag = "COMMIT";
- } else if (sql.startsWith("ROLLBACK")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "ROLLBACK")) {
tag = "ROLLBACK";
- } else if (sql.startsWith("SET ")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "SET ")) {
tag = "SET";
- } else if (sql.startsWith("DECLARE CURSOR")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "DECLARE CURSOR")) {
tag = "DECLARE CURSOR";
- } else if (sql.startsWith("CLOSE CURSOR")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "CLOSE CURSOR")) {
tag = "CLOSE CURSOR";
- } else if (sql.startsWith("FETCH")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "FETCH")) {
tag = "FETCH "+ updateCount;
- } else if (sql.startsWith("MOVE")) {
+ } else if (StringUtil.startsWithIgnoreCase(sql, "MOVE")) {
tag = "MOVE "+ updateCount;
+ } else if (StringUtil.startsWithIgnoreCase(sql, "RELEASE")) {
+ tag = "RELEASE "+ updateCount;
+ } else if (StringUtil.startsWithIgnoreCase(sql, "SAVEPOINT")) {
+ tag = "SAVEPOINT "+ updateCount;
}
else {
tag = sql;
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-10-05 20:52:01 UTC (rev 3533)
+++ trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2011-10-06 02:25:05 UTC (rev 3534)
@@ -128,7 +128,7 @@
config.setSSLConfiguration(sslConfig);
addr = new InetSocketAddress(0);
config.setBindAddress(addr.getHostName());
- config.setPortNumber(0);
+ config.setPortNumber(addr.getPort());
odbcTransport = new ODBCSocketListener(config, BufferManagerFactory.getStandaloneBufferManager(), 0, 100000, Mockito.mock(ILogon.class));
odbcTransport.setMaxBufferSize(1000); //set to a small size to ensure buffering over the limit works
FakeServer server = new FakeServer();
13 years, 2 months
teiid SVN: r3533 - in trunk: build/kits/jboss-container/deploy/teiid and 12 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-05 16:52:01 -0400 (Wed, 05 Oct 2011)
New Revision: 3533
Added:
trunk/cache-jbosscache/src/test/java/
trunk/client/src/main/java/org/teiid/jdbc/EnhancedTimer.java
trunk/client/src/test/java/org/teiid/jdbc/TestEnhancedTimer.java
trunk/common-core/src/main/java/org/teiid/core/util/ExecutorUtils.java
trunk/documentation/reference/src/main/docbook/en-US/content/vdbs.xml
Removed:
trunk/client/src/main/java/org/teiid/jdbc/CancellationTimer.java
trunk/client/src/test/java/org/teiid/jdbc/TestCancellationTimer.java
trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml
Modified:
trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/client/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java
trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
trunk/documentation/reference/src/main/docbook/en-US/Reference.xml
trunk/documentation/reference/src/main/docbook/en-US/content/architecture.xml
trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/ThreadReuseExecutor.java
trunk/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
trunk/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java
trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
trunk/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java
Log:
TEIID-1573 adding the ability to set timeouts at the server and vdb level TEIID-1769 fix for hangs from close
Modified: trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
===================================================================
--- trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-10-05 20:52:01 UTC (rev 3533)
@@ -138,6 +138,8 @@
<property name="objectReplicatorName">teiid/replicator</property>
<!-- Set to true for the engine to detect local change events. Should be disabled if using external change data capture tools. (default true) -->
<property name="detectingChangeEvents">true</property>
+ <!-- Set the default query timeout for all queries in milliseconds. 0 indicates no timeout. Lesser timeout values may be set per VDB or by clients. (default 0) -->
+ <property name="queryTimeout">0</property>
</bean>
<!-- An authorization validator that by default uses data role information stored in VDBs -->
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-10-05 20:52:01 UTC (rev 3533)
@@ -30,7 +30,9 @@
<LI><B>File Enhancements</B> - the file translator can now optionally (via the ExceptionIfFileNotFound property) throw an exception if the path refers to a file that doesn't exist. The file resource adapter can be configured to map file names and can prevent parent path .. references. See the Admin Guide or the file-ds.xml template for more.
<LI><B>TEXTTABLE Enhancements</B> - TEXTTABLE can now parse fixed width files that do not use a row delimiter and can optionally produce fixed values that haven't been trimmed.
<LI><B>Temp table transactions</B> - Internal materialized views and temp table usage from a session and within procedures can take advantage of greater transaction support.
- <LI><B>Buffering Improvements</B> - Added the ability to inline memory based or small lobs and added tracking of the memory held by soft references.
+ <LI><B>Buffering Improvements</B> - Added the ability to inline memory based or small lobs and added tracking of the memory held by soft references. Also switched to a LFRU algorithm that significantly reduces writes and read misses with temporary tables.
+ <LI><B>GSSAPI</B> - both the Teiid JDBC client/server and the ODBC pg backend can now support GSSAPI for single sign-on.
+ <LI><B>Server-side Query Timeouts</B> - default query timeouts can be configured at both the VDB (via the query-timeout VDB property) and entire server (via the teiid-jboss-beans.xml queryTimeout property).
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/client/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java
===================================================================
--- trunk/client/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/client/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -109,6 +109,7 @@
private VDB.Status status = VDB.Status.INACTIVE;
private ConnectionType connectionType = VDB.ConnectionType.BY_VERSION;
private boolean removed;
+ private long queryTimeout = Long.MIN_VALUE;
@ManagementProperty(description="Name of the VDB")
@XmlAttribute(name = "name", required = true)
@@ -357,4 +358,16 @@
public boolean isPreview() {
return Boolean.valueOf(getPropertyValue("preview")); //$NON-NLS-1$
}
+
+ public long getQueryTimeout() {
+ if (queryTimeout == Long.MIN_VALUE) {
+ String timeout = getPropertyValue("query-timeout"); //$NON-NLS-1$
+ if (timeout != null) {
+ queryTimeout = Math.max(0, Long.parseLong(timeout));
+ } else {
+ queryTimeout = 0;
+ }
+ }
+ return queryTimeout;
+ }
}
Deleted: trunk/client/src/main/java/org/teiid/jdbc/CancellationTimer.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/CancellationTimer.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/client/src/main/java/org/teiid/jdbc/CancellationTimer.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -1,119 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.jdbc;
-
-import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.jboss.logging.Logger;
-
-/**
- * Specialized timer that actively purges tasks in lg(n) time
- */
-public class CancellationTimer {
-
- private static AtomicLong id = new AtomicLong();
-
- static abstract class CancelTask implements Runnable, Comparable<CancelTask> {
- final long endTime;
- final long seqId = id.getAndIncrement();
-
- public CancelTask(long delay) {
- this.endTime = System.currentTimeMillis() + delay;
- }
-
- @Override
- public int compareTo(CancelTask o) {
- int result = Long.signum(this.endTime - o.endTime);
- if (result == 0) {
- return Long.signum(seqId - o.seqId);
- }
- return result;
- }
- public boolean equals(Object obj) {
- return obj == this;
- }
- }
-
- private TreeSet<CancelTask> cancelQueue = new TreeSet<CancelTask>();
- private Thread thread;
-
- public CancellationTimer(String name) {
- thread = new Thread(new Runnable() {
-
- @Override
- public void run() {
- while (true) {
- try {
- doCancellations();
- } catch (InterruptedException e) {
- break;
- }
- }
- }
- }, name);
- thread.setDaemon(true);
- thread.start();
- }
-
- private void doCancellations() throws InterruptedException {
- CancelTask task = null;
- synchronized (this) {
- if (cancelQueue.isEmpty()) {
- this.wait();
- return;
- }
- task = cancelQueue.first();
- long toWait = task.endTime - System.currentTimeMillis();
- if (toWait > 0) {
- this.wait(toWait);
- return;
- }
- cancelQueue.pollFirst();
- }
- try {
- task.run();
- } catch (Throwable t) {
- Logger.getLogger(CancellationTimer.class).error("Unexpected exception running task", t); //$NON-NLS-1$
- }
- }
-
- public void add(CancelTask task) {
- synchronized (this) {
- this.cancelQueue.add(task);
- this.notifyAll();
- }
- }
-
- public void remove(CancelTask task) {
- synchronized (this) {
- this.cancelQueue.remove(task);
- this.notifyAll();
- }
- }
-
- synchronized int getQueueSize() {
- return cancelQueue.size();
- }
-
-}
Copied: trunk/client/src/main/java/org/teiid/jdbc/EnhancedTimer.java (from rev 3517, trunk/client/src/main/java/org/teiid/jdbc/CancellationTimer.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/EnhancedTimer.java (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/EnhancedTimer.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.jboss.logging.Logger;
+import org.teiid.core.util.ExecutorUtils;
+
+/**
+ * Specialized timer that can purge tasks in lg(n) time
+ * Uses lock escalation to minimize contention for adding/removing tasks.
+ * Will only hold a thread while there are pending tasks.
+ */
+public class EnhancedTimer {
+
+ private static final Logger LOGGER = Logger.getLogger(EnhancedTimer.class);
+ private static AtomicLong id = new AtomicLong();
+
+ public class Task implements Comparable<Task>, Runnable {
+ final long endTime;
+ final long seqId = id.getAndIncrement();
+ final Runnable task;
+
+ public Task(Runnable task, long delay) {
+ this.endTime = System.currentTimeMillis() + delay;
+ this.task = task;
+ }
+
+ @Override
+ public void run() {
+ this.task.run();
+ }
+
+ @Override
+ public int compareTo(Task o) {
+ int result = Long.signum(this.endTime - o.endTime);
+ if (result == 0) {
+ return Long.signum(seqId - o.seqId);
+ }
+ return result;
+ }
+
+ public boolean cancel() {
+ lock.readLock().lock();
+ try {
+ return queue.remove(this);
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+ }
+
+ private final ConcurrentSkipListSet<Task> queue = new ConcurrentSkipListSet<Task>();
+ private final Executor taskExecutor;
+ private final Executor bossExecutor;
+ private boolean running;
+ private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+ /**
+ * Constructs a new Timer that directly executes tasks off of a single-thread thread pool.
+ * @param name
+ */
+ public EnhancedTimer(final String name) {
+ this.taskExecutor = ExecutorUtils.getDirectExecutor();
+ this.bossExecutor = ExecutorUtils.newFixedThreadPool(1, name);
+ }
+
+ public EnhancedTimer(Executor bossExecutor, Executor taskExecutor) {
+ this.taskExecutor = taskExecutor;
+ this.bossExecutor = bossExecutor;
+ }
+
+ private void start() {
+ bossExecutor.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ while (doCancellations()) {
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+ });
+ running = true;
+ }
+
+ private boolean doCancellations() throws InterruptedException {
+ Task task = null;
+ lock.writeLock().lock();
+ try {
+ if (queue.isEmpty()) {
+ synchronized (this) {
+ lock.writeLock().unlock();
+ running = false;
+ return false;
+ }
+ }
+ task = queue.first();
+ long toWait = task.endTime - System.currentTimeMillis();
+ if (toWait > 0) {
+ synchronized (this) {
+ lock.writeLock().unlock();
+ this.wait(toWait);
+ return true; //try again (guards against spurious wake-ups)
+ }
+ }
+ queue.pollFirst();
+ } finally {
+ if (lock.writeLock().isHeldByCurrentThread()) {
+ lock.writeLock().unlock();
+ }
+ }
+ try {
+ taskExecutor.execute(task);
+ } catch (Throwable t) {
+ LOGGER.error("Unexpected exception running task", t); //$NON-NLS-1$
+ }
+ return true;
+ }
+
+ /**
+ * Add a delayed task
+ * @param task
+ * @param delay in ms
+ * @return a cancellable Task
+ */
+ public Task add(Runnable task, long delay) {
+ Task result = new Task(task, delay);
+ lock.readLock().lock();
+ try {
+ if (this.queue.add(result)
+ && this.queue.first() == result) {
+ //only need to synchronize when this is the first task
+ synchronized (this) {
+ if (!running) {
+ start();
+ }
+ this.notifyAll();
+ }
+ }
+ } catch (NoSuchElementException e) {
+ //shouldn't happen
+ } finally {
+ lock.readLock().unlock();
+ }
+ return result;
+ }
+
+ public int getQueueSize() {
+ return queue.size();
+ }
+
+}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/EnhancedTimer.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -63,19 +63,18 @@
import org.teiid.core.types.SQLXMLImpl;
import org.teiid.core.util.SqlUtil;
import org.teiid.core.util.StringUtil;
-import org.teiid.jdbc.CancellationTimer.CancelTask;
+import org.teiid.jdbc.EnhancedTimer.Task;
import org.teiid.net.TeiidURL;
public class StatementImpl extends WrapperImpl implements TeiidStatement {
private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
- static CancellationTimer cancellationTimer = new CancellationTimer("Teiid Statement Timeout"); //$NON-NLS-1$
+ static EnhancedTimer cancellationTimer = new EnhancedTimer("Teiid Statement Timeout"); //$NON-NLS-1$
- private static final class QueryTimeoutCancelTask extends CancelTask {
+ private static final class QueryTimeoutCancelTask implements Runnable {
private WeakReference<StatementImpl> ref;
- private QueryTimeoutCancelTask(long delay, StatementImpl stmt) {
- super(delay);
+ private QueryTimeoutCancelTask(StatementImpl stmt) {
this.ref = new WeakReference<StatementImpl>(stmt);
}
@@ -98,6 +97,8 @@
// integer indicating no maximum limit - used in some metadata-ish methods.
private static final int NO_LIMIT = 0;
+
+ private QueryTimeoutCancelTask cancelTask = new QueryTimeoutCancelTask(this);
//######## Configuration state #############
private ConnectionImpl driverConnection;
@@ -571,12 +572,11 @@
ResultsFuture.CompletionListener<ResultsMessage> compeletionListener = null;
if (queryTimeoutMS > 0) {
- final CancelTask c = new QueryTimeoutCancelTask(queryTimeoutMS, this);
- cancellationTimer.add(c);
+ final Task c = cancellationTimer.add(cancelTask, queryTimeoutMS);
compeletionListener = new ResultsFuture.CompletionListener<ResultsMessage>() {
@Override
public void onCompletion(ResultsFuture<ResultsMessage> future) {
- cancellationTimer.remove(c);
+ c.cancel();
}
};
}
Deleted: trunk/client/src/test/java/org/teiid/jdbc/TestCancellationTimer.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestCancellationTimer.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestCancellationTimer.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -1,58 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.jdbc;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-import org.teiid.jdbc.CancellationTimer.CancelTask;
-
-@SuppressWarnings("nls")
-public class TestCancellationTimer {
-
- private final class SimpleCancelTask extends CancelTask {
- private SimpleCancelTask(long delay) {
- super(delay);
- }
-
- @Override
- public void run() {
- }
- }
-
- @Test public void testRemove() {
- CancellationTimer ct = new CancellationTimer("foo");
- SimpleCancelTask sct = new SimpleCancelTask(20000);
- ct.add(sct);
- SimpleCancelTask sct1 = new SimpleCancelTask(30000);
- ct.add(sct1);
- SimpleCancelTask sct2 = new SimpleCancelTask(10000);
- ct.add(sct2);
- assertEquals(3, ct.getQueueSize());
- ct.remove(sct2);
- ct.remove(sct1);
- ct.remove(sct);
- assertEquals(0, ct.getQueueSize());
- }
-
-}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestEnhancedTimer.java (from rev 3514, trunk/client/src/test/java/org/teiid/jdbc/TestCancellationTimer.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestEnhancedTimer.java (rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestEnhancedTimer.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.teiid.jdbc.EnhancedTimer.Task;
+
+@SuppressWarnings("nls")
+public class TestEnhancedTimer {
+
+ private final class SimpleCancelTask implements Runnable {
+ @Override
+ public void run() {
+ }
+ }
+
+ @Test public void testRemove() {
+ EnhancedTimer ct = new EnhancedTimer("foo");
+ SimpleCancelTask sct = new SimpleCancelTask();
+ Task tt = ct.add(sct, 20000);
+ Task tt1 = ct.add(sct, 20000);
+ assertTrue(tt.compareTo(tt1) < 0);
+ Task tt2 = ct.add(sct, 10000);
+ assertEquals(3, ct.getQueueSize());
+ tt.cancel();
+ tt1.cancel();
+ tt2.cancel();
+ assertEquals(0, ct.getQueueSize());
+ }
+
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestEnhancedTimer.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/common-core/src/main/java/org/teiid/core/util/ExecutorUtils.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ExecutorUtils.java (rev 0)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ExecutorUtils.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -0,0 +1,59 @@
+/*
+ * 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.core.util;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class ExecutorUtils {
+
+ /**
+ * Creates a fixed thread pool with named daemon threads that will expire after 60 seconds of
+ * inactivity.
+ * @param nThreads
+ * @param name
+ * @return
+ */
+ public static ExecutorService newFixedThreadPool(int nThreads, String name) {
+ ThreadPoolExecutor tpe = new ThreadPoolExecutor(nThreads, nThreads,
+ 60L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory(name));
+ tpe.allowCoreThreadTimeOut(true);
+ return tpe;
+ }
+
+ private static Executor direct = new Executor() {
+
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+ };
+
+ public static Executor getDirectExecutor() {
+ return direct;
+ }
+}
Property changes on: trunk/common-core/src/main/java/org/teiid/core/util/ExecutorUtils.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/documentation/reference/src/main/docbook/en-US/Reference.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/Reference.xml 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/documentation/reference/src/main/docbook/en-US/Reference.xml 2011-10-05 20:52:01 UTC (rev 3533)
@@ -58,7 +58,7 @@
<xi:include href="content/transaction_support.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/dataroles.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/system_schema.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="content/multisource.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/vdbs.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/translators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/federated_planning.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/architecture.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/architecture.xml 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/architecture.xml 2011-10-05 20:52:01 UTC (rev 3533)
@@ -123,17 +123,25 @@
actually support this method.</para>
</section>
<section>
- <title>Timeouts</title>
- <para>Timeouts in Teiid are managed on the client-side,
- in the JDBC API (which underlies both SOAP and ODBC access).
- Timeouts are only relevant for the first record returned. If the
+ <title>User Query Timeouts</title>
+ <para>User query timeouts in Teiid can be managed on the client-side or the server-side.
+ Timeouts are only relevant for the first record returned. If the
first record has not been received by the client within the
- specified timeout period, a ‘cancel’ command is issued to the
+ specified timeout period, a 'cancel' command is issued to the
server for the request and no results are returned to the
- client. The cancel command is issued by the JDBC API without the
- client’s intervention. See the Client Developers Guide for more on setting
- statement timeouts via the connection property "QUERYTIMEOUT" and see the Java JDBC API for setting
- the query timeout via <code>java.sql.Statement.setQueryTimeout</code> method.</para>
+ client. The cancel command is issued asynchronously without the
+ client’s intervention.
+ </para><para>
+ The JDBC API uses the query timeout set by the <code>java.sql.Statement.setQueryTimeout</code> method.
+ You may also set a default statement timeout via the connection property "QUERYTIMEOUT".
+ ODBC clients may also utilize QUERYTIMEOUT as an execution property via a set statement to control the default timeout setting.
+ See the Client Developers Guide for more on connection/execution properties and set statements.</para>
+ <para>Server-side timeouts start when the query is received by the engine. There may be a skew from the when the
+ client issued the query due to network latency or server load that may slow the processing of IO work.
+ The timeout will be cancelled if the first result is sent back before the timeout has ended.
+ See the <xref linkend="vdbs"/> section for more on setting the query-timeout VDB property.
+ See the Admin Guide for more on modifying the &jboss-beans; file to set default query timeout for all queries.
+ </para>
</section>
</section>
<section>
Deleted: trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml 2011-10-05 20:52:01 UTC (rev 3533)
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
-<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
-%CustomDTD;
-]>
-<chapter id="multisource">
- <title>Multi-source models</title>
- <para>Multi-source models can be used to quickly access data in multiple sources with homogeneous metadata.
- Since all sources utilize the same physical metadata, this feature is most appropriate for accessing the same source type with multiple instances.
- <para>A model is marked as supporting multi-source by setting the property supports-multi-source-bindings to true.
- With supports-multi-source-bindings set to true, 1 or more uniquely named source elements can be added to the model.
- See <xref linkend="dynamic_vdbs"/> for a full template of the vdb.xml.</para>
- A physical table in a multi-source model is effectively treated as a view that is a
- union all of the actual physical table from each of the configured sources. These tables tables are implicitly partitioned on a string pseudo-column "source_name".
- The "source_name" column will be available to your use queries for a multi-source model regardless of whether it is explicitly part of the metadata.
- The source_name column value for a particular row is the source name used to obtain that row.
- More complex partitioning scenarios, such as heterogeneous sources or list partitioning will require the use of a <xref linkend="partitioned_union"/></para>
- <para>In some scenarios, the source_name column can be manually added to the physical metadata in the Designer tool so that virtual layer logic can be multi-source aware.
- It is important to understand that a column or IN procedure parameter named source_name will always be treated as the explicit form of the multi-source source_name column
- and will no longer be treated as an actual physical column or procedure parameter.</para>
- <section>
- <title>Multi-source SELECTs</title>
- <para>A multi-source SELECT may use the source_name column anywhere a column reference is allowed. As a final stage of planning, a source query will be generated against each source and each instance of the source_name column replaced by the appropriate value.
- If the resulting query still needs executed, it is sent to the source. If the WHERE clause evaluates to always false, then the query is pruned from the result. All results are then unioned together and returned as the full result.
- </para>
- </section>
- <section>
- <title>Multi-source INSERTs</title>
- <para>A multi-source INSERT may use the source_name column as an insert target column to specify which source should be targeted by the INSERT. Only a INSERT using the VALUES clause is supported and the source_name column value must be a literal.
- If the source_name column is not part of the INSERT column, then the INSERT will be issued against every source. The sum of the update counts will be returned as the resultant update count.</para>
- </section>
- <section>
- <title>Multi-source UPDATEs</title>
- <para>A multi-source delete functions just like SELECT, however it is not possible to use the source_name column as a target column in the change set. Any other usage of the source_name column will be the appropriate value for each source.
- If the WHERE clause evaluates to always false, then no update will be issued to the source. The sum of the update counts will be returned as the resultant update count.</para>
- </section>
- <section>
- <title>Multi-source DELETEs</title>
- <para>A multi-source delete functions just like SELECT. Any usage of the source_name column will be the appropriate value for each source.
- If the WHERE clause evaluates to always false, then no delete will be issued to the source. The sum of the update counts will be returned as the resultant update count.</para>
- </section>
- <section>
- <title>Multi-source Stored Procedures</title>
- <para>A physical stored procedures requires the manual addition of a string source_name parameter to allow for specifying which source the procedure is executed on.
- If the source_name parameter is not added or if named parameters are used and the source_name parameter is allowed to default to a null value, then the procedure will be executed on
- each source and the results unioned together.</para>
- <para>It is not possible to execute procedures that required to return IN/OUT, OUT, or RETURN parameters values on more than 1 source at a time.</para>
- </section>
- <section>
- <title>Additional Concerns</title>
- <para>When running under a transaction of in a mode that detects the need for a transation and multiple updates are performed, an attempt will be made to enlist each source in the same XA transaction.</para>
- </section>
-</chapter>
\ No newline at end of file
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-10-05 20:52:01 UTC (rev 3533)
@@ -1196,293 +1196,5 @@
</table>
</section>
</section>
-
- <section id="dynamic_vdbs">
- <title>Dynamic VDBs</title>
- <para>
- Teiid integration is available via a "Dynamic VDB" without the need for Teiid Designer
- tooling. While this mode of operation does not yet allow for the creation of view
- layers, the underlying sources can still be queried as if they are a single source. See
- the kit's "teiid-example/dynamicvdb-*" for working examples.
- </para>
- <para>
- To build a dynamic VDB, you'll need to create a
- <filename><replaceable>SOME-NAME</replaceable>-vdb.xml</filename> file. The XML file captures
- information about the VDB, the sources it integrate, and preferences for importing metadata.
- </para>
-
- <note>
- <para>
- VDB name pattern must adhere to "-vdb.xml" for the Teiid VDB deployer to
- recognize this file as a dynamic VDB.
- </para>
- </note>
-
- <para>
- my-vdb.xml: (The vdb-deployer.xml schema for this file is available in the schema
- folder under the docs with the Teiid distribution.)
- </para>
-
- <programlisting role="XML" language="XML"><![CDATA[<vdb name="${vdb-name}" version="${vdb-version}">
-
- <property name="UseConnectorMetadata" value="..." />
-
- <!-- define a model fragment for each data source -->
- <model name="${model-name}">
-
- <property name="..." value="..." />
- ...
-
- <source name="${source-name}" translator-name="${translator-name}"
-
- connection-jndi-name="${deployed-jndi-name}">
- ...
- </model>
-
- <!-- create translator instances that override default properties -->
-
- <translator name="${translator-name}" type="${translator-type}" />
-
- <property name="..." value="..." />
- ...
-
- </translator>
-</vdb>]]></programlisting>
-
- <section>
- <title>VDB Element</title>
- <itemizedlist>
- <title>Attributes</title>
- <listitem>
- <para>
- <emphasis>name</emphasis>
- </para>
- <para>
- The name of the VDB. The VDB name
- referenced through the driver or datasource during the connection time.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>version</emphasis>
- </para>
- <para>
- The version of the VDB (should be an
- positive integer). This determines the deployed directory location
- (see Name), and provides an explicit versioning mechanism to the VDB
- name.
- </para>
- </listitem>
- </itemizedlist>
-
- <itemizedlist>
- <title>Property Elements</title>
- <listitem>
- <para>
- <emphasis>UseConnectorMetadata</emphasis>
- </para>
- <para>
- Setting to use connector
- supplied metadata. Can be "true" or "cached". "true" will obtain
- metadata once for every launch of Teiid. "cached" will save a file
- containing the metadata into the
- <filename><replaceable>PROFILE</replaceable>/data/teiid</filename> directory
- </para>
- </listitem>
- </itemizedlist>
-
- </section>
-
- <section>
- <title>Model Element</title>
- <itemizedlist>
- <title>Attributes</title>
- <listitem>
- <para>
- <emphasis>name</emphasis>
- </para>
- <para>
- The name of the model is used as a
- top level schema name for all of the metadata imported from the
- connector. The name should be unique among all Models in the VDB and
- should not contain the '.' character.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>version</emphasis>
- </para>
- <para>
- The version of the VDB (should be an
- positive integer). This determines the deployed directory location
- (see Name), and provides an explicit versioning mechanism to the VDB
- name.
- </para>
- </listitem>
- </itemizedlist>
-
- <itemizedlist>
- <title>Source Element</title>
- <listitem>
- <para>
- <emphasis>name</emphasis>
- </para>
- <para>
- The name of the source to use for this
- model. This can be any name you like, but will typically be the same
- as the model name. Having a name different than the model name is
- only useful in multi-source scenarios.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>translator-name</emphasis>
- </para>
- <para>
- The name or type of the Teiid Translator to use. Possible values include
- the built-in types (ws, file, ldap, oracle, sqlserver, db2, derby, etc.)
- and translators defined in the translators section.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>connection-jndi-name</emphasis>
- </para>
- <para>
- The JNDI name of this source's connection factory. There should be a
- corresponding "-ds.xml" file that defines the connection factory in
- the JBoss AS. Check out the deploying VDB dependencies section for
- info. You also need to deploy these connection factories before you
- can deploy the VDB.
- </para>
- </listitem>
- </itemizedlist>
-
- <itemizedlist>
- <title>Property Elements</title>
- <listitem>
- <para>
- <emphasis>importer.<propertyname></emphasis>
- </para>
- <para>
- Property to be used by the connector importer for the model for purposes
- importing metadata. See possible property name/values in the
- Translator specific section. Note that using these properties you
- can narrow or widen the data elements available for integration.
- </para>
- </listitem>
- </itemizedlist>
-
- </section>
- <section>
- <title>Translator Element</title>
- <itemizedlist>
- <title>Attributes</title>
- <listitem>
- <para>
- <emphasis>name</emphasis>
- </para>
- <para>
- The name of the the Translator. Referenced by the source element.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>type</emphasis>
- </para>
- <para>
- The base type of the Translator. Can be one of the built-in types (ws,
- file, ldap, oracle, sqlserver, db2, derby, etc.).
- </para>
- </listitem>
- </itemizedlist>
-
- <itemizedlist>
- <title>Property Elements</title>
- <listitem>
- <para>
- Set a value that overrides a translator default property. See
- possible property name/values in the Translator specific section.
- </para>
- </listitem>
- </itemizedlist>
- </section>
-
- </section>
- <section>
- <title>Multi-Source Models and VDB</title>
- <para>
- When you have multiple instances of data that are using identical schema
- (horizontal sharding), Teiid can help you aggregate data across all the
- instances, using "multi-source" models. In this scenario, instead of
- creating/importing a model for every data source, user needs to define one
- source model that represents the schema and configure multiple data "sources"
- underneath it. During runtime, when a query issued against this model, the query
- engine analyzes the information and gathers the required data from all the
- sources configured and aggregates the results and provides in a single result set.
- </para>
-
- <para>
- To mark a model as multi-source, the user needs to supply property called
- <property>supports-multi-source-bindings</property>, in the "vdb.xml" file.
- Also, the user needs to define multiple sources. Here is code example showing dynamic vdb with single model with
- multiple sources defined.
- </para>
-
- <programlisting role="XML" language="XML"><![CDATA[<vdb name="vdbname" version="1">
- <model visible="true" type="PHYSICAL" name="Customers" path="/Test/Customers.xmi">
- <property name="supports-multi-source-bindings" value="true"/>
- <source name="chicago"
- translator-name="oracle" connection-jndi-name="chicago-customers"/>
- <source name="newyork"
- translator-name="oracle" connection-jndi-name="newyork-customers"/>
- <source name="la"
- translator-name="oracle" connection-jndi-name="la-customers"/>
- </model>
-</vdb>]]></programlisting>
-
- <para>
- In the above example, the VDB defined has single model called <literal>Customers</literal>,
- that has multiple sources (<literal>chicago</literal>, <literal>newyork</literal>,
- and <literal>la</literal>) that define different instances of data. Every
- time a model is marked as "multi-source", the
- runtime engine adds a additional column called "SOURCE_NAME" to every table in
- that model. This column maps to the source's name from the XML. In
- the above XML code that would be <literal>chicago</literal>, <literal>la</literal>,
- <literal>newyork</literal>. This allows queries like the following:
- </para>
-
- <programlisting language="SQL"><![CDATA[select * from table where SOURCE_NAME = 'newyork'
-update table column=value where SOURCE_NAME='chicago'
-delete from table where column = x and SOURCE_NAME='la'
-insert into table (column, SOURCE_NAME) VALUES ('value', 'newyork')]]></programlisting>
-
- <para>
- Note that when user do not supply the "SOURCE_NAME" in the criteria, the command applies
- to all the sources. If SOURCE_NAME supplied, the query is executed only aginst the source specified.
- Another useful feature along with this feature is
- "partial results" to skip unavailable sources if they are down.
- </para>
-
- <note>
- <para>
- Currently the tooling support for managing the multi-source feature is
- limited, so if you need to use this feature build the VDB as usual in
- the Teiid Designer and then edit the "vdb.xml" file in the VDB archive
- using a Text editor to add the additional sources as defined above.
- You must deploy a separate data source for each source defined in the xml file.
- </para>
- </note>
-
- <note>
- <para>
- If you would like to use "SOURCE_NAME" in your transformations to control which sources are accessed or updated,
- you would manually need to add this extra column on your view table in
- the Designer. This column will not be automatically added on the source table, when you import
- the medata from source.
- </para>
- </note>
- </section>
-
</chapter>
\ No newline at end of file
Copied: trunk/documentation/reference/src/main/docbook/en-US/content/vdbs.xml (from rev 3382, trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml)
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/vdbs.xml (rev 0)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/vdbs.xml 2011-10-05 20:52:01 UTC (rev 3533)
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
+%CustomDTD;
+]>
+<chapter id="vdbs">
+ <title>VDBs</title>
+ <section>
+ <title>VDB Definition</title>
+ <para>A VDB or virtual database definition is contained in an XML file.
+ For .vdb archive files created in the design tool, this file is embedded in the archive and most field can be updated through tooling.
+ The XML schema for this file can be found in the teiid-docs/schema directory.</para>
+ <example>
+ <title>Example VDB XML</title>
+ <programlisting role="XML" language="XML"><![CDATA[<vdb name="${vdb-name}" version="${vdb-version}">
+
+ <!-- VDB properties -->
+ <property name="UseConnectorMetadata" value="..." />
+ ...
+
+ <!-- define a model fragment for each data source -->
+ <model name="${model-name}">
+
+ <property name="..." value="..." />
+ ...
+
+ <source name="${source-name}" translator-name="${translator-name}"
+
+ connection-jndi-name="${deployed-jndi-name}">
+ ...
+ </model>
+
+ <!-- create translator instances that override default properties -->
+
+ <translator name="${translator-name}" type="${translator-type}" />
+
+ <property name="..." value="..." />
+ ...
+
+ </translator>
+</vdb>]]></programlisting>
+</example>
+
+ <section>
+ <title>VDB Element</title>
+ <itemizedlist>
+ <title>Attributes</title>
+ <listitem>
+ <para>
+ <emphasis>name</emphasis>
+ </para>
+ <para>
+ The name of the VDB. The VDB name
+ referenced through the driver or datasource during the connection time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>version</emphasis>
+ </para>
+ <para>
+ The version of the VDB (should be an
+ positive integer). This determines the deployed directory location
+ (see Name), and provides an explicit versioning mechanism to the VDB
+ name.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Property Elements</title>
+ <listitem>
+ <para>
+ <emphasis>UseConnectorMetadata</emphasis>
+ </para>
+ <para>
+ Setting to use connector
+ supplied metadata. Can be "true" or "cached". "true" will obtain
+ metadata once for every launch of Teiid. "cached" will save a file
+ containing the metadata into the
+ <filename><replaceable>PROFILE</replaceable>/data/teiid</filename> directory
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>query-timeout</emphasis>
+ </para>
+ <para>
+ Sets the default query timeout in milliseconds for queries executed against this VDB. 0 indicates that the server default query timeout should be used. Defaults to 0. Will have no effect if the server default query timeout is set to a lesser value. Note that clients can still set their own timeouts that will be managed on the client side.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </section>
+
+ <section>
+ <title>Model Element</title>
+ <itemizedlist>
+ <title>Attributes</title>
+ <listitem>
+ <para>
+ <emphasis>name</emphasis>
+ </para>
+ <para>
+ The name of the model is used as a
+ top level schema name for all of the metadata imported from the
+ connector. The name should be unique among all Models in the VDB and
+ should not contain the '.' character.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>version</emphasis>
+ </para>
+ <para>
+ The version of the VDB (should be an
+ positive integer). This determines the deployed directory location
+ (see Name), and provides an explicit versioning mechanism to the VDB
+ name.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Source Element</title>
+ <listitem>
+ <para>
+ <emphasis>name</emphasis>
+ </para>
+ <para>
+ The name of the source to use for this
+ model. This can be any name you like, but will typically be the same
+ as the model name. Having a name different than the model name is
+ only useful in multi-source scenarios.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>translator-name</emphasis>
+ </para>
+ <para>
+ The name or type of the Teiid Translator to use. Possible values include
+ the built-in types (ws, file, ldap, oracle, sqlserver, db2, derby, etc.)
+ and translators defined in the translators section.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>connection-jndi-name</emphasis>
+ </para>
+ <para>
+ The JNDI name of this source's connection factory. There should be a
+ corresponding "-ds.xml" file that defines the connection factory in
+ the JBoss AS. Check out the deploying VDB dependencies section for
+ info. You also need to deploy these connection factories before you
+ can deploy the VDB.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Property Elements</title>
+ <listitem>
+ <para>
+ <emphasis>importer.<propertyname></emphasis>
+ </para>
+ <para>
+ Property to be used by the connector importer for the model for purposes
+ importing metadata. See possible property name/values in the
+ Translator specific section. Note that using these properties you
+ can narrow or widen the data elements available for integration.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </section>
+ <section>
+ <title>Translator Element</title>
+ <itemizedlist>
+ <title>Attributes</title>
+ <listitem>
+ <para>
+ <emphasis>name</emphasis>
+ </para>
+ <para>
+ The name of the the Translator. Referenced by the source element.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>type</emphasis>
+ </para>
+ <para>
+ The base type of the Translator. Can be one of the built-in types (ws,
+ file, ldap, oracle, sqlserver, db2, derby, etc.).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Property Elements</title>
+ <listitem>
+ <para>
+ Set a value that overrides a translator default property. See
+ possible property name/values in the Translator specific section.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section id="dynamic_vdbs">
+ <title>Dynamic VDBs</title>
+ <para>
+ Teiid integration is available via a "Dynamic VDB" without the need for Teiid Designer
+ tooling. While this mode of operation does not yet allow for the creation of view
+ layers, the underlying sources can still be queried as if they are a single source. See
+ the kit's "teiid-example/dynamicvdb-*" for working examples.
+ </para>
+
+ <para>
+ To build a dynamic VDB, you'll need to create a
+ <filename><replaceable>SOME-NAME</replaceable>-vdb.xml</filename> file. The XML file captures
+ information about the VDB, the sources it integrate, and preferences for importing metadata.
+ </para>
+
+ <note>
+ <para>
+ VDB name pattern must adhere to "-vdb.xml" for the Teiid VDB deployer to
+ recognize this file as a dynamic VDB.
+ </para>
+ </note>
+
+ <para>
+ my-vdb.xml: (The vdb-deployer.xml schema for this file is available in the schema
+ folder under the docs with the Teiid distribution.)
+ </para>
+
+ </section>
+ <section>
+ <title>Multi-Source Models and VDB</title>
+ <para>
+ Multi-source models can be used to quickly access data in multiple sources with homogeneous metadata.
+ When you have multiple instances of data that are using identical schema
+ (horizontal sharding), Teiid can help you aggregate data across all the
+ instances, using "multi-source" models. In this scenario, instead of
+ creating/importing a model for every data source, user needs to define one
+ source model that represents the schema and configure multiple data "sources"
+ underneath it. During runtime, when a query issued against this model, the query
+ engine analyzes the information and gathers the required data from all the
+ sources configured and aggregates the results and provides in a single result set.
+ Since all sources utilize the same physical metadata, this feature is most appropriate for accessing the same source type with multiple instances.
+ </para>
+
+ <para>
+ To mark a model as multi-source, the user needs to supply property called
+ <property>supports-multi-source-bindings</property>, in the "vdb.xml" file.
+ Also, the user needs to define multiple sources. Here is code example showing dynamic vdb with single model with
+ multiple sources defined.
+ </para>
+
+ <programlisting role="XML" language="XML"><![CDATA[<vdb name="vdbname" version="1">
+ <model visible="true" type="PHYSICAL" name="Customers" path="/Test/Customers.xmi">
+ <property name="supports-multi-source-bindings" value="true"/>
+ <source name="chicago"
+ translator-name="oracle" connection-jndi-name="chicago-customers"/>
+ <source name="newyork"
+ translator-name="oracle" connection-jndi-name="newyork-customers"/>
+ <source name="la"
+ translator-name="oracle" connection-jndi-name="la-customers"/>
+ </model>
+</vdb>]]></programlisting>
+
+ <para>
+ In the above example, the VDB defined has single model called <literal>Customers</literal>,
+ that has multiple sources (<literal>chicago</literal>, <literal>newyork</literal>,
+ and <literal>la</literal>) that define different instances of data. Every
+ time a model is marked as "multi-source", the
+ runtime engine adds a additional column called "SOURCE_NAME" to every table in
+ that model. This column maps to the source's name from the XML. In
+ the above XML code that would be <literal>chicago</literal>, <literal>la</literal>,
+ <literal>newyork</literal>. This allows queries like the following:
+ </para>
+
+ <programlisting language="SQL"><![CDATA[select * from table where SOURCE_NAME = 'newyork'
+update table column=value where SOURCE_NAME='chicago'
+delete from table where column = x and SOURCE_NAME='la'
+insert into table (column, SOURCE_NAME) VALUES ('value', 'newyork')]]></programlisting>
+
+ <para>
+ Note that when user do not supply the "SOURCE_NAME" in the criteria, the command applies
+ to all the sources. If SOURCE_NAME supplied, the query is executed only aginst the source specified.
+ Another useful feature along with this feature is
+ "partial results" to skip unavailable sources if they are down.
+ </para>
+
+ <para>More complex partitioning scenarios, such as heterogeneous sources or list partitioning will require the use of a <xref linkend="partitioned_union"/>.</para>
+
+ <note>
+ <para>
+ Currently the tooling support for managing the multi-source feature is
+ limited, so if you need to use this feature build the VDB as usual in
+ the Teiid Designer and then edit the "vdb.xml" file in the VDB archive
+ using a Text editor to add the additional sources as defined above.
+ You must deploy a separate data source for each source defined in the xml file.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ If you would like to use "SOURCE_NAME" in your transformations to control which sources are accessed or updated,
+ you would manually need to add this extra column on your view table in
+ the Designer. This column will not be automatically added on the source table, when you import
+ the medata from source.
+
+ It is important to understand that a column or IN procedure parameter named source_name in multi-source mode will always be treated as the explicit form of the multi-source source_name column
+ and will no longer be treated as an actual physical column or procedure parameter.</para>
+ </note>
+
+ <section>
+ <title>Multi-source SELECTs</title>
+ <para>A multi-source SELECT may use the source_name column anywhere a column reference is allowed. As a final stage of planning, a source query will be generated against each source and each instance of the source_name column replaced by the appropriate value.
+ If the resulting query still needs executed, it is sent to the source. If the WHERE clause evaluates to always false, then the query is pruned from the result. All results are then unioned together and returned as the full result.
+ </para>
+ </section>
+ <section>
+ <title>Multi-source INSERTs</title>
+ <para>A multi-source INSERT may use the source_name column as an insert target column to specify which source should be targeted by the INSERT. Only a INSERT using the VALUES clause is supported and the source_name column value must be a literal.
+ If the source_name column is not part of the INSERT column, then the INSERT will be issued against every source. The sum of the update counts will be returned as the resultant update count.</para>
+ </section>
+ <section>
+ <title>Multi-source UPDATEs</title>
+ <para>A multi-source delete functions just like SELECT, however it is not possible to use the source_name column as a target column in the change set. Any other usage of the source_name column will be the appropriate value for each source.
+ If the WHERE clause evaluates to always false, then no update will be issued to the source. The sum of the update counts will be returned as the resultant update count.</para>
+ </section>
+ <section>
+ <title>Multi-source DELETEs</title>
+ <para>A multi-source delete functions just like SELECT. Any usage of the source_name column will be the appropriate value for each source.
+ If the WHERE clause evaluates to always false, then no delete will be issued to the source. The sum of the update counts will be returned as the resultant update count.</para>
+ </section>
+ <section>
+ <title>Multi-source Stored Procedures</title>
+ <para>A physical stored procedures requires the manual addition of a string source_name parameter to allow for specifying which source the procedure is executed on.
+ If the source_name parameter is not added or if named parameters are used and the source_name parameter is allowed to default to a null value, then the procedure will be executed on
+ each source and the results unioned together.</para>
+ <para>It is not possible to execute procedures that required to return IN/OUT, OUT, or RETURN parameters values on more than 1 source at a time.</para>
+ </section>
+ <section>
+ <title>Additional Concerns</title>
+ <para>When running under a transaction of in a mode that detects the need for a transaction and multiple updates are performed, an attempt will be made to enlist each source in the same XA transaction.</para>
+ </section>
+ </section>
+
+</chapter>
\ No newline at end of file
Property changes on: trunk/documentation/reference/src/main/docbook/en-US/content/vdbs.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -44,8 +44,6 @@
private int timeSliceInMilli = DEFAULT_PROCESSOR_TIMESLICE;
private int maxRowsFetchSize = DEFAULT_FETCH_SIZE;
private int lobChunkSizeInKB = 100;
- private boolean useDataRoles = true;
- private boolean allowCreateTemporaryTablesByDefault = true;
private int queryThresholdInSecs = DEFAULT_QUERY_THRESHOLD;
private boolean exceptionOnMaxSourceRows = true;
private int maxSourceRows = -1;
@@ -55,9 +53,9 @@
private int maxODBCLobSizeAllowed = 5*1024*1024; // 5 MB
private int userRequestSourceConcurrency = DEFAULT_USER_REQUEST_SOURCE_CONCURRENCY;
private boolean detectingChangeEvents = true;
+ private long queryTimeout;
private transient AuthorizationValidator authorizationValidator;
- private boolean allowFunctionCallsByDefault;
@ManagementProperty(description="Max active plans (default 20). Increase this value, and max threads, on highly concurrent systems - but ensure that the underlying pools can handle the increased load without timeouts.")
public int getMaxActivePlans() {
@@ -219,5 +217,14 @@
public void setDetectingChangeEvents(boolean detectingChangeEvents) {
this.detectingChangeEvents = detectingChangeEvents;
}
+
+ @ManagementProperty(description="Set the default query timeout for all queries in milliseconds. 0 indicates no timeout. Lesser timeout values may be set per VDB or by clients. (default 0)")
+ public void setQueryTimeout(long queryTimeout) {
+ this.queryTimeout = queryTimeout;
+ }
+
+ public long getQueryTimeout() {
+ return queryTimeout;
+ }
}
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-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -22,6 +22,7 @@
package org.teiid.dqp.internal.process;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -32,6 +33,7 @@
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
@@ -61,6 +63,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.Streamable;
+import org.teiid.core.util.ExecutorUtils;
import org.teiid.dqp.internal.process.ThreadReuseExecutor.PrioritizedRunnable;
import org.teiid.dqp.message.AtomicRequestMessage;
import org.teiid.dqp.message.RequestID;
@@ -69,6 +72,7 @@
import org.teiid.dqp.service.TransactionService;
import org.teiid.dqp.service.TransactionContext.Scope;
import org.teiid.events.EventDistributor;
+import org.teiid.jdbc.EnhancedTimer;
import org.teiid.logging.CommandLogMessage;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
@@ -208,6 +212,8 @@
private CacheFactory cacheFactory;
private AuthorizationValidator authorizationValidator;
+
+ private EnhancedTimer cancellationTimer;
/**
* perform a full shutdown and wait for 10 seconds for all threads to finish
@@ -341,9 +347,27 @@
request.setAuthorizationValidator(this.authorizationValidator);
request.setUserRequestConcurrency(this.getUserRequestSourceConcurrency());
ResultsFuture<ResultsMessage> resultsFuture = new ResultsFuture<ResultsMessage>();
- RequestWorkItem workItem = new RequestWorkItem(this, requestMsg, request, resultsFuture.getResultsReceiver(), requestID, workContext);
+ final RequestWorkItem workItem = new RequestWorkItem(this, requestMsg, request, resultsFuture.getResultsReceiver(), requestID, workContext);
logMMCommand(workItem, Event.NEW, null);
addRequest(requestID, workItem, state);
+ long timeout = workContext.getVDB().getQueryTimeout();
+ timeout = Math.min(timeout>0?timeout:Long.MAX_VALUE, config.getQueryTimeout()>0?config.getQueryTimeout():Long.MAX_VALUE);
+ if (timeout < Long.MAX_VALUE) {
+ workItem.setCancelTask(this.cancellationTimer.add(new Runnable() {
+ WeakReference<RequestWorkItem> workItemRef = new WeakReference<RequestWorkItem>(workItem);
+ @Override
+ public void run() {
+ try {
+ RequestWorkItem wi = workItemRef.get();
+ if (wi != null) {
+ wi.requestCancel();
+ }
+ } catch (TeiidComponentException e) {
+ LogManager.logError(LogConstants.CTX_DQP, e, "Error processing cancellation task."); //$NON-NLS-1$
+ }
+ }
+ }, timeout));
+ }
boolean runInThread = DQPWorkContext.getWorkContext().useCallingThread() || requestMsg.isSync();
synchronized (waitingPlans) {
if (runInThread || currentlyActivePlans <= maxActivePlans) {
@@ -721,6 +745,10 @@
prepPlanCache.setBufferManager(this.bufferManager);
this.processWorkerPool = new ThreadReuseExecutor(DQPConfiguration.PROCESS_PLAN_QUEUE_NAME, config.getMaxThreads());
+ //we don't want cancellations waiting on normal processing, so they get a small dedicated pool
+ //TODO: overflow to the worker pool
+ Executor timeoutExecutor = ExecutorUtils.newFixedThreadPool(3, "Server Side Timeout"); //$NON-NLS-1$
+ this.cancellationTimer = new EnhancedTimer(timeoutExecutor, timeoutExecutor);
this.maxActivePlans = config.getMaxActivePlans();
if (this.maxActivePlans > config.getMaxThreads()) {
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-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -60,6 +60,7 @@
import org.teiid.dqp.service.TransactionService;
import org.teiid.dqp.service.TransactionContext.Scope;
import org.teiid.jdbc.SQLStates;
+import org.teiid.jdbc.EnhancedTimer.Task;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
@@ -169,6 +170,8 @@
protected boolean useCallingThread;
private volatile boolean hasThread;
+ private Task cancelTask;
+
public RequestWorkItem(DQPCore dqpCore, RequestMessage requestMsg, Request request, ResultsReceiver<ResultsMessage> receiver, RequestID requestID, DQPWorkContext workContext) {
this.requestMsg = requestMsg;
this.requestID = requestID;
@@ -292,37 +295,9 @@
LogManager.logDetail(LogConstants.CTX_DQP, "Request Thread", requestID, "- time slice expired"); //$NON-NLS-1$ //$NON-NLS-2$
this.moreWork();
} catch (Throwable e) {
- LogManager.logDetail(LogConstants.CTX_DQP, e, "Request Thread", requestID, "- error occurred"); //$NON-NLS-1$ //$NON-NLS-2$
-
- if (!isCanceled()) {
- dqpCore.logMMCommand(this, Event.ERROR, null);
- //Case 5558: Differentiate between system level errors and
- //processing errors. Only log system level errors as errors,
- //log the processing errors as warnings only
- if(e instanceof TeiidProcessingException) {
- Throwable cause = e;
- while (cause.getCause() != null && cause.getCause() != cause) {
- cause = cause.getCause();
- }
- StackTraceElement[] elems = cause.getStackTrace();
- Object elem = null;
- if (elems.length > 0) {
- elem = cause.getStackTrace()[0];
- } else {
- elem = cause.getMessage();
- }
- LogManager.logWarning(LogConstants.CTX_DQP, QueryPlugin.Util.getString("ProcessWorker.processing_error", e.getMessage(), requestID, e.getClass().getName(), elem)); //$NON-NLS-1$
- }else {
- LogManager.logError(LogConstants.CTX_DQP, e, QueryPlugin.Util.getString("ProcessWorker.error", requestID)); //$NON-NLS-1$
- }
- }
-
- this.processingException = e;
- this.state = ProcessingState.CLOSE;
+ handleThrowable(e);
} finally {
- if (this.state == ProcessingState.CLOSE && !isClosed) {
- attemptClose();
- } else if (isClosed) {
+ if (isClosed) {
/*
* since there may be a client waiting notify them of a problem
*/
@@ -330,11 +305,43 @@
this.processingException = new IllegalStateException("Request is already closed"); //$NON-NLS-1$
}
sendError();
+ } else if (this.state == ProcessingState.CLOSE) {
+ close();
}
suspend();
}
}
+ private void handleThrowable(Throwable e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, e, "Request Thread", requestID, "- error occurred"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ if (!isCanceled()) {
+ dqpCore.logMMCommand(this, Event.ERROR, null);
+ //Case 5558: Differentiate between system level errors and
+ //processing errors. Only log system level errors as errors,
+ //log the processing errors as warnings only
+ if(e instanceof TeiidProcessingException) {
+ Throwable cause = e;
+ while (cause.getCause() != null && cause.getCause() != cause) {
+ cause = cause.getCause();
+ }
+ StackTraceElement[] elems = cause.getStackTrace();
+ Object elem = null;
+ if (elems.length > 0) {
+ elem = cause.getStackTrace()[0];
+ } else {
+ elem = cause.getMessage();
+ }
+ LogManager.logWarning(LogConstants.CTX_DQP, QueryPlugin.Util.getString("ProcessWorker.processing_error", e.getMessage(), requestID, e.getClass().getName(), elem)); //$NON-NLS-1$
+ }else {
+ LogManager.logError(LogConstants.CTX_DQP, e, QueryPlugin.Util.getString("ProcessWorker.error", requestID)); //$NON-NLS-1$
+ }
+ }
+
+ this.processingException = e;
+ this.state = ProcessingState.CLOSE;
+ }
+
private void resume() throws XATransactionException {
if (this.transactionState == TransactionState.ACTIVE && this.transactionContext.getTransaction() != null) {
this.transactionService.resume(this.transactionContext);
@@ -387,65 +394,77 @@
* Client close is currently implemented as asynch.
* Any errors that occur will not make it to the client, instead we just log them here.
*/
- protected void attemptClose() {
+ protected void close() {
int rowcount = -1;
- if (this.resultsBuffer != null) {
- if (this.processor != null) {
- this.processor.closeProcessing();
-
- if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
- LogManager.logDetail(LogConstants.CTX_DQP, "Removing tuplesource for the request " + requestID); //$NON-NLS-1$
- }
- rowcount = resultsBuffer.getRowCount();
- if (this.cid == null || !this.doneProducingBatches) {
- resultsBuffer.remove();
- } else {
- try {
- this.resultsBuffer.persistLobs();
- } catch (TeiidComponentException e) {
- LogManager.logDetail(LogConstants.CTX_DQP, QueryPlugin.Util.getString("failed_to_cache")); //$NON-NLS-1$
+ try {
+ cancelCancelTask();
+ if (this.resultsBuffer != null) {
+ if (this.processor != null) {
+ this.processor.closeProcessing();
+
+ if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
+ LogManager.logDetail(LogConstants.CTX_DQP, "Removing tuplesource for the request " + requestID); //$NON-NLS-1$
+ }
+ rowcount = resultsBuffer.getRowCount();
+ if (this.cid == null || !this.doneProducingBatches) {
+ resultsBuffer.remove();
+ } else {
+ try {
+ this.resultsBuffer.persistLobs();
+ } catch (TeiidComponentException e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, QueryPlugin.Util.getString("failed_to_cache")); //$NON-NLS-1$
+ }
}
+
+ for (DataTierTupleSource connectorRequest : getConnectorRequests()) {
+ connectorRequest.fullyCloseSource();
+ }
}
+
+ this.resultsBuffer = null;
- for (DataTierTupleSource connectorRequest : getConnectorRequests()) {
- connectorRequest.fullyCloseSource();
- }
+ if (!this.lobStreams.isEmpty()) {
+ List<LobWorkItem> lobs = null;
+ synchronized (lobStreams) {
+ lobs = new ArrayList<LobWorkItem>(this.lobStreams.values());
+ }
+ for (LobWorkItem lobWorkItem : lobs) {
+ lobWorkItem.close();
+ }
+ }
}
-
- this.resultsBuffer = null;
-
- if (!this.lobStreams.isEmpty()) {
- List<LobWorkItem> lobs = null;
- synchronized (lobStreams) {
- lobs = new ArrayList<LobWorkItem>(this.lobStreams.values());
+
+ if (this.transactionState == TransactionState.ACTIVE) {
+ this.transactionState = TransactionState.DONE;
+ if (transactionContext.getTransactionType() == TransactionContext.Scope.REQUEST) {
+ try {
+ this.transactionService.rollback(transactionContext);
+ } catch (XATransactionException e1) {
+ LogManager.logWarning(LogConstants.CTX_DQP, e1, QueryPlugin.Util.getString("ProcessWorker.failed_rollback")); //$NON-NLS-1$
+ }
+ } else {
+ suspend();
}
- for (LobWorkItem lobWorkItem : lobs) {
- lobWorkItem.close();
- }
}
- }
-
- if (this.transactionState == TransactionState.ACTIVE) {
- this.transactionState = TransactionState.DONE;
- if (transactionContext.getTransactionType() == TransactionContext.Scope.REQUEST) {
- try {
- this.transactionService.rollback(transactionContext);
- } catch (XATransactionException e1) {
- LogManager.logWarning(LogConstants.CTX_DQP, e1, QueryPlugin.Util.getString("ProcessWorker.failed_rollback")); //$NON-NLS-1$
- }
+ } catch (Throwable t) {
+ handleThrowable(t);
+ } finally {
+ isClosed = true;
+
+ dqpCore.removeRequest(this);
+
+ if (this.processingException != null) {
+ sendError();
} else {
- suspend();
+ dqpCore.logMMCommand(this, Event.END, rowcount);
}
}
-
- isClosed = true;
+ }
- dqpCore.removeRequest(this);
-
- if (this.processingException != null) {
- sendError();
- } else {
- dqpCore.logMMCommand(this, Event.END, rowcount);
+ private void cancelCancelTask() {
+ if (this.cancelTask != null) {
+ this.cancelTask.cancel();
+ this.cancelTask = null;
}
}
@@ -643,6 +662,7 @@
receiver = this.resultsReceiver;
this.resultsReceiver = null;
}
+ cancelCancelTask();
receiver.receiveResults(response);
return result;
}
@@ -936,5 +956,9 @@
void scheduleWork(Runnable r, int priority, long delay) {
dqpCore.scheduleWork(r, priority, delay);
}
+
+ public void setCancelTask(Task cancelTask) {
+ this.cancelTask = cancelTask;
+ }
}
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/ThreadReuseExecutor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/ThreadReuseExecutor.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/ThreadReuseExecutor.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -291,7 +291,8 @@
synchronized (poolLock) {
if (success) {
completedCount++;
- r = queue.poll();
+ //we only poll if successful, to let the exception handling happen immediately otherwise
+ r = queue.poll();
}
if (!success || r == null) {
threads.remove(t);
@@ -301,10 +302,12 @@
}
}
}
- long warnTime = warnWaitTime;
- if (r != null && System.currentTimeMillis() - r.getCreationTime() > warnTime) {
- LogManager.logWarning(LogConstants.CTX_RUNTIME, QueryPlugin.Util.getString("WorkerPool.Max_thread", maximumPoolSize, poolName, highestQueueSize, warnTime)); //$NON-NLS-1$
- warnWaitTime*=2; //we don't really care if this is synchronized
+ if (success) {
+ long warnTime = warnWaitTime;
+ if (r != null && System.currentTimeMillis() - r.getCreationTime() > warnTime) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, QueryPlugin.Util.getString("WorkerPool.Max_thread", maximumPoolSize, poolName, highestQueueSize, warnTime)); //$NON-NLS-1$
+ warnWaitTime*=2; //we don't really care if this is synchronized
+ }
}
t.setName(name);
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -197,11 +197,13 @@
this.bufferMgr.releaseBuffers(reserved);
reserved = 0;
processorClosed = true;
- try {
- processPlan.close();
- } catch (TeiidComponentException e1){
- LogManager.logDetail(LogConstants.CTX_DQP, e1, "Error closing processor"); //$NON-NLS-1$
- }
+ if (initialized) {
+ try {
+ processPlan.close();
+ } catch (TeiidComponentException e1){
+ LogManager.logDetail(LogConstants.CTX_DQP, e1, "Error closing processor"); //$NON-NLS-1$
+ }
+ }
}
@Override
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -167,14 +167,14 @@
String sql = "SELECT hasRole('foo')"; //$NON-NLS-1$
String userName = "logon"; //$NON-NLS-1$
ResultsMessage rm = helpExecute(sql, userName);
- assertTrue((Boolean)rm.getResults()[0].get(0));
+ assertTrue((Boolean)rm.getResultsList().get(0).get(0));
}
@Test public void testNotHasRole() throws Exception {
String sql = "SELECT hasRole('bar')"; //$NON-NLS-1$
String userName = "logon"; //$NON-NLS-1$
ResultsMessage rm = helpExecute(sql, userName);
- assertFalse((Boolean)rm.getResults()[0].get(0));
+ assertFalse((Boolean)rm.getResultsList().get(0).get(0));
}
@Test public void testUser1() throws Exception {
@@ -235,14 +235,14 @@
String sql = "SELECT env('sessionid') as SessionID"; //$NON-NLS-1$
String userName = "1"; //$NON-NLS-1$
ResultsMessage rm = helpExecute(sql, userName);
- assertEquals("1", rm.getResults()[0].get(0)); //$NON-NLS-1$
+ assertEquals("1", rm.getResultsList().get(0).get(0)); //$NON-NLS-1$
}
@Test public void testEnvSessionIdMixedCase() throws Exception {
String sql = "SELECT env('sEsSIonId') as SessionID"; //$NON-NLS-1$
String userName = "1"; //$NON-NLS-1$
ResultsMessage rm = helpExecute(sql, userName);
- assertEquals("1", rm.getResults()[0].get(0)); //$NON-NLS-1$
+ assertEquals("1", rm.getResultsList().get(0).get(0)); //$NON-NLS-1$
}
@Test public void testTxnAutoWrap() throws Exception {
@@ -265,13 +265,13 @@
agds.setCaps(caps);
ResultsMessage rm = helpExecute(sql, "a"); //$NON-NLS-1$
//we test for > 0 here because the autogen service doesn't obey the limit
- assertTrue(rm.getResults().length > 0);
+ assertTrue(rm.getResultsList().size() > 0);
}
@Test public void testLimitCompensation1() throws Exception {
String sql = "SELECT * FROM VQT.SmallA_2589g LIMIT 1, 1"; //$NON-NLS-1$
ResultsMessage rm = helpExecute(sql, "a"); //$NON-NLS-1$
- assertEquals(1, rm.getResults().length);
+ assertEquals(1, rm.getResultsList().size());
}
@@ -317,13 +317,13 @@
assertNull(rm.getException());
int rowsPerBatch = 8;
- assertEquals(rowsPerBatch, rm.getResults().length);
+ assertEquals(rowsPerBatch, rm.getResultsList().size());
RequestWorkItem item = core.getRequestWorkItem(DQPWorkContext.getWorkContext().getRequestID(reqMsg.getExecutionId()));
message = core.processCursorRequest(reqMsg.getExecutionId(), 9, rowsPerBatch);
rm = message.get(500000, TimeUnit.MILLISECONDS);
assertNull(rm.getException());
- assertEquals(rowsPerBatch, rm.getResults().length);
+ assertEquals(rowsPerBatch, rm.getResultsList().size());
//ensure that we are idle
for (int i = 0; i < 10 && item.getThreadState() != ThreadState.IDLE; i++) {
Thread.sleep(100);
@@ -429,17 +429,17 @@
Future<ResultsMessage> message = core.executeRequest(reqMsg.getExecutionId(), reqMsg);
ResultsMessage rm = message.get(500000, TimeUnit.MILLISECONDS);
assertNull(rm.getException());
- assertEquals(1, rm.getResults().length);
+ assertEquals(1, rm.getResultsList().size());
message = core.processCursorRequest(reqMsg.getExecutionId(), 3, 2);
rm = message.get(500000, TimeUnit.MILLISECONDS);
assertNull(rm.getException());
- assertEquals(1, rm.getResults().length);
+ assertEquals(1, rm.getResultsList().size());
message = core.processCursorRequest(reqMsg.getExecutionId(), 3, 2);
rm = message.get(500000, TimeUnit.MILLISECONDS);
assertNull(rm.getException());
- assertEquals(0, rm.getResults().length);
+ assertEquals(0, rm.getResultsList().size());
}
@Test public void testPreparedPlanInvalidation() throws Exception {
@@ -448,19 +448,19 @@
int sessionid = 1; //$NON-NLS-1$
RequestMessage reqMsg = exampleRequestMessage(sql);
ResultsMessage rm = execute(userName, sessionid, reqMsg);
- assertEquals(1, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(1, rm.getResultsList().size()); //$NON-NLS-1$
sql = "select * from #temp"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
reqMsg.setStatementType(StatementType.PREPARED);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(10, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(10, rm.getResultsList().size()); //$NON-NLS-1$
sql = "select * from #temp"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
reqMsg.setStatementType(StatementType.PREPARED);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(10, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(10, rm.getResultsList().size()); //$NON-NLS-1$
assertEquals(1, this.core.getPrepPlanCache().getCacheHitCount());
@@ -470,13 +470,13 @@
sql = "delete from #temp where a12345 = '11'"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(1, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(1, rm.getResultsList().size()); //$NON-NLS-1$
sql = "select * from #temp"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
reqMsg.setStatementType(StatementType.PREPARED);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(10, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(10, rm.getResultsList().size()); //$NON-NLS-1$
assertEquals(2, this.core.getPrepPlanCache().getCacheHitCount());
@@ -484,13 +484,13 @@
sql = "delete from #temp"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(1, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(1, rm.getResultsList().size()); //$NON-NLS-1$
sql = "select * from #temp"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
reqMsg.setStatementType(StatementType.PREPARED);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(0, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(0, rm.getResultsList().size()); //$NON-NLS-1$
assertEquals(2, this.core.getPrepPlanCache().getCacheHitCount());
}
@@ -502,13 +502,13 @@
RequestMessage reqMsg = exampleRequestMessage(sql);
reqMsg.setUseResultSetCache(true);
ResultsMessage rm = execute(userName, sessionid, reqMsg);
- assertEquals(10, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(10, rm.getResultsList().size()); //$NON-NLS-1$
sql = "select * FROM vqt.SmallB"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
reqMsg.setUseResultSetCache(true);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(10, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(10, rm.getResultsList().size()); //$NON-NLS-1$
assertEquals(1, this.core.getRsCache().getCacheHitCount());
@@ -517,13 +517,13 @@
sql = "delete from bqt1.smalla"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(1, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(1, rm.getResultsList().size()); //$NON-NLS-1$
sql = "select * FROM vqt.SmallB"; //$NON-NLS-1$
reqMsg = exampleRequestMessage(sql);
reqMsg.setUseResultSetCache(true);
rm = execute(userName, sessionid, reqMsg);
- assertEquals(10, rm.getResults().length); //$NON-NLS-1$
+ assertEquals(10, rm.getResultsList().size()); //$NON-NLS-1$
assertEquals(1, this.core.getRsCache().getCacheHitCount());
}
@@ -539,7 +539,7 @@
@Override
public void onCompletion(ResultsFuture<ResultsMessage> future) {
try {
- final BlobType bt = (BlobType)future.get().getResults()[0].get(0);
+ final BlobType bt = (BlobType)future.get().getResultsList().get(0).get(0);
t.bt = bt;
t.workContext = DQPWorkContext.getWorkContext();
synchronized (t) {
@@ -556,6 +556,15 @@
assertNotNull(t.chunkFuture.get().getBytes());
}
+ @Test public void testServerTimeout() throws Exception {
+ RequestMessage reqMsg = exampleRequestMessage("select to_bytes(stringkey, 'utf-8') FROM BQT1.SmallA");
+ reqMsg.setTxnAutoWrapMode(RequestMessage.TXN_WRAP_OFF);
+ agds.setSleep(100);
+ this.config.setQueryTimeout(1);
+ ResultsMessage rm = execute("A", 1, reqMsg);
+ assertNotNull(rm.getException());
+ }
+
public void helpTestVisibilityFails(String sql) throws Exception {
RequestMessage reqMsg = exampleRequestMessage(sql);
reqMsg.setTxnAutoWrapMode(RequestMessage.TXN_WRAP_OFF);
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -29,13 +29,13 @@
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
-import java.util.concurrent.Executor;
import org.junit.Before;
import org.junit.Test;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.util.ExecutorUtils;
import org.teiid.dqp.internal.process.CachedResults;
import org.teiid.dqp.internal.process.QueryProcessorFactoryImpl;
import org.teiid.dqp.internal.process.SessionAwareCache;
@@ -75,13 +75,7 @@
SessionAwareCache<CachedResults> cache = new SessionAwareCache<CachedResults>();
cache.setBufferManager(bm);
- Executor executor = new Executor() {
- @Override
- public void execute(Runnable command) {
- command.run();
- }
- };
- dataManager = new TempTableDataManager(hdm, bm, executor, cache);
+ dataManager = new TempTableDataManager(hdm, bm, ExecutorUtils.getDirectExecutor(), cache);
}
private void execute(String sql, List<?>... expectedResults) throws Exception {
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -39,7 +39,6 @@
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
-import java.util.concurrent.Executor;
import org.junit.Test;
import org.teiid.client.metadata.ParameterInfo;
@@ -55,6 +54,7 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.XMLType;
+import org.teiid.core.util.ExecutorUtils;
import org.teiid.dqp.internal.process.CachedResults;
import org.teiid.dqp.internal.process.PreparedPlan;
import org.teiid.dqp.internal.process.QueryProcessorFactoryImpl;
@@ -254,13 +254,7 @@
if (!(dataManager instanceof TempTableDataManager)) {
SessionAwareCache<CachedResults> cache = new SessionAwareCache<CachedResults>();
cache.setBufferManager(bufferMgr);
- Executor executor = new Executor() {
- @Override
- public void execute(Runnable command) {
- command.run();
- }
- };
- dataManager = new TempTableDataManager(dataManager, bufferMgr, executor, cache);
+ dataManager = new TempTableDataManager(dataManager, bufferMgr, ExecutorUtils.getDirectExecutor(), cache);
}
if (context.getQueryProcessorFactory() == null) {
context.setQueryProcessorFactory(new QueryProcessorFactoryImpl(bufferMgr, dataManager, new DefaultCapabilitiesFinder(), null, context.getMetadata()));
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -22,39 +22,30 @@
package org.teiid.query.processor;
+import static org.junit.Assert.*;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import org.junit.Test;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.common.buffer.TupleBatch;
import org.teiid.common.buffer.TupleBuffer;
import org.teiid.common.buffer.TupleSource;
+import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidException;
-import org.teiid.query.processor.BatchCollector;
-import org.teiid.query.processor.QueryProcessor;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.util.CommandContext;
-import junit.framework.TestCase;
-
-
/**
*/
-public class TestQueryProcessor extends TestCase {
+public class TestQueryProcessor {
- /**
- * Constructor for TestQueryProcessor.
- * @param name
- */
- public TestQueryProcessor(String name) {
- super(name);
- }
-
- public void helpTestProcessor(FakeProcessorPlan plan, long timeslice, List[] expectedResults) throws TeiidException {
+ public void helpTestProcessor(FakeProcessorPlan plan, List[] expectedResults) throws TeiidException {
BufferManager bufferMgr = BufferManagerFactory.getStandaloneBufferManager();
FakeDataManager dataManager = new FakeDataManager();
@@ -85,14 +76,14 @@
tsID.remove();
}
- public void testNoResults() throws Exception {
+ @Test public void testNoResults() throws Exception {
List elements = new ArrayList();
elements.add(new ElementSymbol("a")); //$NON-NLS-1$
FakeProcessorPlan plan = new FakeProcessorPlan(elements, null);
- helpTestProcessor(plan, 1000, new List[0]);
+ helpTestProcessor(plan, new List[0]);
}
- public void testBlockNoResults() throws Exception {
+ @Test public void testBlockNoResults() throws Exception {
List elements = new ArrayList();
elements.add(new ElementSymbol("a")); //$NON-NLS-1$
@@ -103,10 +94,10 @@
batches.add(batch);
FakeProcessorPlan plan = new FakeProcessorPlan(elements, batches);
- helpTestProcessor(plan, 1000, new List[0]);
+ helpTestProcessor(plan, new List[0]);
}
- public void testProcessWithOccasionalBlocks() throws Exception {
+ @Test public void testProcessWithOccasionalBlocks() throws Exception {
List elements = new ArrayList();
elements.add(new ElementSymbol("a")); //$NON-NLS-1$
@@ -137,6 +128,18 @@
}
FakeProcessorPlan plan = new FakeProcessorPlan(elements, batches);
- helpTestProcessor(plan, 1000, expectedResults);
+ helpTestProcessor(plan, expectedResults);
}
+
+ @Test public void testCloseBeforeInitialization() throws TeiidComponentException {
+ BufferManager bufferMgr = BufferManagerFactory.getStandaloneBufferManager();
+ FakeDataManager dataManager = new FakeDataManager();
+
+ CommandContext context = new CommandContext("pid", "group", null, null, 1); //$NON-NLS-1$ //$NON-NLS-2$
+
+ QueryProcessor processor = new QueryProcessor(null, context, bufferMgr, dataManager);
+ processor.closeProcessing();
+ }
+
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -28,7 +28,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.Executor;
import javax.transaction.RollbackException;
import javax.transaction.Status;
@@ -44,6 +43,7 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.util.ExecutorUtils;
import org.teiid.dqp.internal.process.CachedResults;
import org.teiid.dqp.internal.process.SessionAwareCache;
import org.teiid.dqp.service.TransactionContext;
@@ -94,13 +94,7 @@
BufferManager bm = BufferManagerFactory.getStandaloneBufferManager();
SessionAwareCache<CachedResults> cache = new SessionAwareCache<CachedResults>();
cache.setBufferManager(bm);
- Executor executor = new Executor() {
- @Override
- public void execute(Runnable command) {
- command.run();
- }
- };
- dataManager = new TempTableDataManager(fdm, bm, executor, cache);
+ dataManager = new TempTableDataManager(fdm, bm, ExecutorUtils.getDirectExecutor(), cache);
}
@Test public void testRollbackNoExisting() throws Exception {
Modified: trunk/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java 2011-10-05 20:22:43 UTC (rev 3532)
+++ trunk/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java 2011-10-05 20:52:01 UTC (rev 3533)
@@ -56,7 +56,7 @@
DQPConfiguration dqpConfig = new DQPConfiguration();
dqpConfig.setMaxActivePlans(2);
- FakeServer server = new FakeServer();
+ FakeServer server = new FakeServer(dqpConfig);
server.setUseCallingThread(false);
server.deployVDB("parts", UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb");
13 years, 2 months
teiid SVN: r3532 - in branches/7.4.x: engine/src/main/java/org/teiid/query/processor and 3 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-05 16:22:43 -0400 (Wed, 05 Oct 2011)
New Revision: 3532
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java
branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java
branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java
Log:
TEIID-1769 fix for hangs from close
Modified: branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-10-05 16:09:13 UTC (rev 3531)
+++ branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-10-05 20:22:43 UTC (rev 3532)
@@ -291,37 +291,9 @@
LogManager.logDetail(LogConstants.CTX_DQP, "Request Thread", requestID, "- time slice expired"); //$NON-NLS-1$ //$NON-NLS-2$
this.moreWork();
} catch (Throwable e) {
- LogManager.logDetail(LogConstants.CTX_DQP, e, "Request Thread", requestID, "- error occurred"); //$NON-NLS-1$ //$NON-NLS-2$
-
- if (!isCanceled()) {
- dqpCore.logMMCommand(this, Event.ERROR, null);
- //Case 5558: Differentiate between system level errors and
- //processing errors. Only log system level errors as errors,
- //log the processing errors as warnings only
- if(e instanceof TeiidProcessingException) {
- Throwable cause = e;
- while (cause.getCause() != null && cause.getCause() != cause) {
- cause = cause.getCause();
- }
- StackTraceElement[] elems = cause.getStackTrace();
- Object elem = null;
- if (elems.length > 0) {
- elem = cause.getStackTrace()[0];
- } else {
- elem = cause.getMessage();
- }
- LogManager.logWarning(LogConstants.CTX_DQP, QueryPlugin.Util.getString("ProcessWorker.processing_error", e.getMessage(), requestID, e.getClass().getName(), elem)); //$NON-NLS-1$
- }else {
- LogManager.logError(LogConstants.CTX_DQP, e, QueryPlugin.Util.getString("ProcessWorker.error", requestID)); //$NON-NLS-1$
- }
- }
-
- this.processingException = e;
- this.state = ProcessingState.CLOSE;
+ handleThrowable(e);
} finally {
- if (this.state == ProcessingState.CLOSE && !isClosed) {
- attemptClose();
- } else if (isClosed) {
+ if (isClosed) {
/*
* since there may be a client waiting notify them of a problem
*/
@@ -329,11 +301,42 @@
this.processingException = new IllegalStateException("Request is already closed"); //$NON-NLS-1$
}
sendError();
+ } else if (this.state == ProcessingState.CLOSE) {
+ close();
}
suspend();
}
}
+ private void handleThrowable(Throwable e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, e, "Request Thread", requestID, "- error occurred"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ if (!isCanceled()) {
+ dqpCore.logMMCommand(this, Event.ERROR, null);
+ //Case 5558: Differentiate between system level errors and
+ //processing errors. Only log system level errors as errors,
+ //log the processing errors as warnings only
+ if(e instanceof TeiidProcessingException) {
+ Throwable cause = e;
+ while (cause.getCause() != null && cause.getCause() != cause) {
+ cause = cause.getCause();
+ }
+ StackTraceElement[] elems = cause.getStackTrace();
+ Object elem = null;
+ if (elems.length > 0) {
+ elem = cause.getStackTrace()[0];
+ } else {
+ elem = cause.getMessage();
+ }
+ LogManager.logWarning(LogConstants.CTX_DQP, QueryPlugin.Util.getString("ProcessWorker.processing_error", e.getMessage(), requestID, e.getClass().getName(), elem)); //$NON-NLS-1$
+ }else {
+ LogManager.logError(LogConstants.CTX_DQP, e, QueryPlugin.Util.getString("ProcessWorker.error", requestID)); //$NON-NLS-1$
+ }
+ }
+ this.processingException = e;
+ this.state = ProcessingState.CLOSE;
+ }
+
private void resume() throws XATransactionException {
if (this.transactionState == TransactionState.ACTIVE && this.transactionContext.getTransaction() != null) {
this.transactionService.resume(this.transactionContext);
@@ -386,60 +389,64 @@
* Client close is currently implemented as asynch.
* Any errors that occur will not make it to the client, instead we just log them here.
*/
- protected void attemptClose() {
+ protected void close() {
int rowcount = -1;
- if (this.resultsBuffer != null) {
- if (this.processor != null) {
- this.processor.closeProcessing();
-
- if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
- LogManager.logDetail(LogConstants.CTX_DQP, "Removing tuplesource for the request " + requestID); //$NON-NLS-1$
- }
- rowcount = resultsBuffer.getRowCount();
- if (this.cid == null || !this.doneProducingBatches) {
- resultsBuffer.remove();
- } else {
- try {
- this.resultsBuffer.persistLobs();
- } catch (TeiidComponentException e) {
- LogManager.logDetail(LogConstants.CTX_DQP, QueryPlugin.Util.getString("failed_to_cache")); //$NON-NLS-1$
+ try {
+ if (this.resultsBuffer != null) {
+ if (this.processor != null) {
+ this.processor.closeProcessing();
+
+ if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
+ LogManager.logDetail(LogConstants.CTX_DQP, "Removing tuplesource for the request " + requestID); //$NON-NLS-1$
+ }
+ rowcount = resultsBuffer.getRowCount();
+ if (this.cid == null || !this.doneProducingBatches) {
+ resultsBuffer.remove();
+ } else {
+ try {
+ this.resultsBuffer.persistLobs();
+ } catch (TeiidComponentException e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, QueryPlugin.Util.getString("failed_to_cache")); //$NON-NLS-1$
+ }
}
+
+ for (DataTierTupleSource connectorRequest : this.connectorInfo.values()) {
+ connectorRequest.fullyCloseSource();
+ }
}
+
+ this.resultsBuffer = null;
- for (DataTierTupleSource connectorRequest : this.connectorInfo.values()) {
- connectorRequest.fullyCloseSource();
- }
+ for (LobWorkItem lobWorkItem : this.lobStreams.values()) {
+ lobWorkItem.close();
+ }
}
-
- this.resultsBuffer = null;
-
- for (LobWorkItem lobWorkItem : this.lobStreams.values()) {
- lobWorkItem.close();
+
+ if (this.transactionState == TransactionState.ACTIVE) {
+ this.transactionState = TransactionState.DONE;
+ if (transactionContext.getTransactionType() == TransactionContext.Scope.REQUEST) {
+ try {
+ this.transactionService.rollback(transactionContext);
+ } catch (XATransactionException e1) {
+ LogManager.logWarning(LogConstants.CTX_DQP, e1, QueryPlugin.Util.getString("ProcessWorker.failed_rollback")); //$NON-NLS-1$
+ }
+ } else {
+ suspend();
+ }
}
- }
-
- if (this.transactionState == TransactionState.ACTIVE) {
- this.transactionState = TransactionState.DONE;
- if (transactionContext.getTransactionType() == TransactionContext.Scope.REQUEST) {
- try {
- this.transactionService.rollback(transactionContext);
- } catch (XATransactionException e1) {
- LogManager.logWarning(LogConstants.CTX_DQP, e1, QueryPlugin.Util.getString("ProcessWorker.failed_rollback")); //$NON-NLS-1$
- }
+ } catch (Throwable t) {
+ handleThrowable(t);
+ } finally {
+ isClosed = true;
+
+ dqpCore.removeRequest(this);
+
+ if (this.processingException != null) {
+ sendError();
} else {
- suspend();
+ dqpCore.logMMCommand(this, Event.END, rowcount);
}
}
-
- isClosed = true;
-
- dqpCore.removeRequest(this);
-
- if (this.processingException != null) {
- sendError();
- } else {
- dqpCore.logMMCommand(this, Event.END, rowcount);
- }
}
protected void processNew() throws TeiidProcessingException, TeiidComponentException {
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java 2011-10-05 16:09:13 UTC (rev 3531)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/QueryProcessor.java 2011-10-05 20:22:43 UTC (rev 3532)
@@ -197,11 +197,13 @@
this.bufferMgr.releaseBuffers(reserved);
reserved = 0;
processorClosed = true;
- try {
- processPlan.close();
- } catch (TeiidComponentException e1){
- LogManager.logDetail(LogConstants.CTX_DQP, e1, "Error closing processor"); //$NON-NLS-1$
- }
+ if (initialized) {
+ try {
+ processPlan.close();
+ } catch (TeiidComponentException e1){
+ LogManager.logDetail(LogConstants.CTX_DQP, e1, "Error closing processor"); //$NON-NLS-1$
+ }
+ }
}
@Override
Modified: branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java 2011-10-05 16:09:13 UTC (rev 3531)
+++ branches/7.4.x/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java 2011-10-05 20:22:43 UTC (rev 3532)
@@ -529,6 +529,20 @@
assertNotNull(t.chunkFuture.get().getBytes());
}
+ @Test public void testServerTimeout() throws Exception {
+ RequestMessage reqMsg = exampleRequestMessage("select to_bytes(stringkey, 'utf-8') FROM BQT1.SmallA");
+ reqMsg.setTxnAutoWrapMode(RequestMessage.TXN_WRAP_OFF);
+ agds.setSleep(100);
+ String sessionid = "1";
+ String userName = "A";
+ DQPWorkContext.getWorkContext().getSession().setSessionId(String.valueOf(sessionid));
+ DQPWorkContext.getWorkContext().getSession().setUserName(userName);
+
+ Future<ResultsMessage> message = core.executeRequest(reqMsg.getExecutionId(), reqMsg);
+ core.cancelRequest(reqMsg.getExecutionId());
+ assertNotNull(message.get().getException());
+ }
+
public void helpTestVisibilityFails(String sql) throws Exception {
RequestMessage reqMsg = exampleRequestMessage(sql);
reqMsg.setTxnAutoWrapMode(RequestMessage.TXN_WRAP_OFF);
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java 2011-10-05 16:09:13 UTC (rev 3531)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestQueryProcessor.java 2011-10-05 20:22:43 UTC (rev 3532)
@@ -22,39 +22,30 @@
package org.teiid.query.processor;
+import static org.junit.Assert.*;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import org.junit.Test;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.common.buffer.TupleBatch;
import org.teiid.common.buffer.TupleBuffer;
import org.teiid.common.buffer.TupleSource;
+import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidException;
-import org.teiid.query.processor.BatchCollector;
-import org.teiid.query.processor.QueryProcessor;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.util.CommandContext;
-import junit.framework.TestCase;
-
-
/**
*/
-public class TestQueryProcessor extends TestCase {
+public class TestQueryProcessor {
- /**
- * Constructor for TestQueryProcessor.
- * @param name
- */
- public TestQueryProcessor(String name) {
- super(name);
- }
-
- public void helpTestProcessor(FakeProcessorPlan plan, long timeslice, List[] expectedResults) throws TeiidException {
+ public void helpTestProcessor(FakeProcessorPlan plan, List[] expectedResults) throws TeiidException {
BufferManager bufferMgr = BufferManagerFactory.getStandaloneBufferManager();
FakeDataManager dataManager = new FakeDataManager();
@@ -85,14 +76,14 @@
tsID.remove();
}
- public void testNoResults() throws Exception {
+ @Test public void testNoResults() throws Exception {
List elements = new ArrayList();
elements.add(new ElementSymbol("a")); //$NON-NLS-1$
FakeProcessorPlan plan = new FakeProcessorPlan(elements, null);
- helpTestProcessor(plan, 1000, new List[0]);
+ helpTestProcessor(plan, new List[0]);
}
- public void testBlockNoResults() throws Exception {
+ @Test public void testBlockNoResults() throws Exception {
List elements = new ArrayList();
elements.add(new ElementSymbol("a")); //$NON-NLS-1$
@@ -103,10 +94,10 @@
batches.add(batch);
FakeProcessorPlan plan = new FakeProcessorPlan(elements, batches);
- helpTestProcessor(plan, 1000, new List[0]);
+ helpTestProcessor(plan, new List[0]);
}
- public void testProcessWithOccasionalBlocks() throws Exception {
+ @Test public void testProcessWithOccasionalBlocks() throws Exception {
List elements = new ArrayList();
elements.add(new ElementSymbol("a")); //$NON-NLS-1$
@@ -137,6 +128,16 @@
}
FakeProcessorPlan plan = new FakeProcessorPlan(elements, batches);
- helpTestProcessor(plan, 1000, expectedResults);
+ helpTestProcessor(plan, expectedResults);
}
+
+ @Test public void testCloseBeforeInitialization() throws TeiidComponentException {
+ BufferManager bufferMgr = BufferManagerFactory.getStandaloneBufferManager();
+ FakeDataManager dataManager = new FakeDataManager();
+
+ CommandContext context = new CommandContext("pid", "group", null, null, 1); //$NON-NLS-1$ //$NON-NLS-2$
+
+ QueryProcessor processor = new QueryProcessor(null, context, bufferMgr, dataManager);
+ processor.closeProcessing();
+ }
}
Modified: branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java
===================================================================
--- branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java 2011-10-05 16:09:13 UTC (rev 3531)
+++ branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestJDBCSocketTransport.java 2011-10-05 20:22:43 UTC (rev 3532)
@@ -56,7 +56,7 @@
DQPConfiguration dqpConfig = new DQPConfiguration();
dqpConfig.setMaxActivePlans(2);
- FakeServer server = new FakeServer();
+ FakeServer server = new FakeServer(dqpConfig);
server.setUseCallingThread(false);
server.deployVDB("parts", UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb");
13 years, 2 months
teiid SVN: r3531 - trunk/engine/src/main/java/org/teiid/common/buffer/impl.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-05 12:09:13 -0400 (Wed, 05 Oct 2011)
New Revision: 3531
Modified:
trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
trunk/engine/src/main/java/org/teiid/common/buffer/impl/OrderedCache.java
Log:
TEIID-1750 changing memoryentries to be non-blocking
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2011-10-05 16:05:38 UTC (rev 3530)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2011-10-05 16:09:13 UTC (rev 3531)
@@ -296,8 +296,6 @@
value.setOrderingValue(orderingValue);
}
};
-
- //private LinkedHashMap<Long, CacheEntry> memoryEntries = new LinkedHashMap<Long, CacheEntry>();
//limited size reference caches based upon the memory settings
private WeakReferenceHashedValueCache<CacheEntry> weakReferenceCache;
@@ -554,14 +552,13 @@
int maxToFree = Math.max(maxProcessingKB>>1, reserveBatchKB>>3);
int freed = 0;
while (true) {
- CacheEntry ce = null;
- synchronized (memoryEntries) {
- if (freed > maxToFree || activeBatchKB.get() == 0 || activeBatchKB.get() < reserveBatchKB * .8) {
- break;
- }
- ce = memoryEntries.evict();
- freed += ce.getSizeEstimate();
- activeBatchKB.addAndGet(-ce.getSizeEstimate());
+ if (freed > maxToFree || activeBatchKB.get() == 0 || activeBatchKB.get() < reserveBatchKB * .8) {
+ break;
+ }
+ CacheEntry ce = memoryEntries.evict();
+ freed += ce.getSizeEstimate();
+ activeBatchKB.addAndGet(-ce.getSizeEstimate());
+ synchronized (ce) {
if (ce.isPersistent()) {
continue;
}
@@ -603,12 +600,10 @@
*/
CacheEntry fastGet(Long batch, boolean prefersMemory, boolean retain) {
CacheEntry ce = null;
- synchronized (memoryEntries) {
- if (retain) {
- ce = memoryEntries.get(batch);
- } else {
- ce = memoryEntries.remove(batch);
- }
+ if (retain) {
+ ce = memoryEntries.get(batch);
+ } else {
+ ce = memoryEntries.remove(batch);
}
if (ce != null) {
if (!retain) {
@@ -667,7 +662,7 @@
void addMemoryEntry(CacheEntry ce, CacheEntry previous) {
persistBatchReferences();
- synchronized (memoryEntries) {
+ synchronized (ce) {
if (previous != null) {
ce.setOrderingValue(previous.getOrderingValue());
}
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/impl/OrderedCache.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/impl/OrderedCache.java 2011-10-05 16:05:38 UTC (rev 3530)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/impl/OrderedCache.java 2011-10-05 16:09:13 UTC (rev 3531)
@@ -22,30 +22,24 @@
package org.teiid.common.buffer.impl;
-import java.util.Comparator;
-import java.util.HashMap;
import java.util.Map;
-import java.util.TreeMap;
+import java.util.NavigableMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
public abstract class OrderedCache<K, V> {
- protected HashMap<K, V> map = new HashMap<K, V>();
- protected TreeMap<V, K> expirationQueue;
-
- public OrderedCache() {
- expirationQueue = new TreeMap<V, K>();
- }
-
- public OrderedCache(Comparator<? super V> comparator) {
- expirationQueue = new TreeMap<V, K>(comparator);
- }
-
+ protected Map<K, V> map = new ConcurrentHashMap<K, V>();
+ protected NavigableMap<V, K> expirationQueue = new ConcurrentSkipListMap<V, K>();
+
public V get(K key) {
V result = map.get(key);
if (result != null) {
- expirationQueue.remove(result);
- recordAccess(key, result, false);
- expirationQueue.put(result, key);
+ synchronized (result) {
+ expirationQueue.remove(result);
+ recordAccess(key, result, false);
+ expirationQueue.put(result, key);
+ }
}
return result;
}
@@ -53,7 +47,9 @@
public V remove(K key) {
V result = map.remove(key);
if (result != null) {
- expirationQueue.remove(result);
+ synchronized (result) {
+ expirationQueue.remove(result);
+ }
}
return result;
}
@@ -61,10 +57,14 @@
public V put(K key, V value) {
V result = map.put(key, value);
if (result != null) {
- expirationQueue.remove(result);
+ synchronized (result) {
+ expirationQueue.remove(result);
+ }
}
- recordAccess(key, value, result == null);
- expirationQueue.put(value, key);
+ synchronized (value) {
+ recordAccess(key, value, result == null);
+ expirationQueue.put(value, key);
+ }
return result;
}
@@ -73,8 +73,7 @@
if (entry == null) {
return null;
}
- map.remove(entry.getValue());
- return entry.getKey();
+ return map.remove(entry.getValue());
}
public int size() {
13 years, 2 months
teiid SVN: r3530 - in trunk/engine/src: test/java/org/teiid/query/processor and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-10-05 12:05:38 -0400 (Wed, 05 Oct 2011)
New Revision: 3530
Modified:
trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
Log:
TEIID-1768 fix for invalid locking
Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java 2011-10-05 15:32:08 UTC (rev 3529)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java 2011-10-05 16:05:38 UTC (rev 3530)
@@ -230,7 +230,6 @@
int process() throws ExpressionEvaluationException, TeiidComponentException, TeiidProcessingException {
int reserved = reserveBuffers();
- boolean held = lock.writeLock().isHeldByCurrentThread();
lock.writeLock().lock();
boolean success = false;
try {
@@ -265,9 +264,7 @@
}
} finally {
bm.releaseBuffers(reserved);
- if (!held) {
- lock.writeLock().unlock();
- }
+ lock.writeLock().unlock();
close();
}
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-10-05 15:32:08 UTC (rev 3529)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-10-05 16:05:38 UTC (rev 3530)
@@ -277,6 +277,19 @@
}
//should revert back to original
execute("select count(*) from x", new List[] {Arrays.asList(2)}); //$NON-NLS-1$
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ execute("select count(e1) from x", new List[] {Arrays.asList(2)});
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ t.start();
+ t.join(2000);
+ assertFalse(t.isAlive());
}
@Test public void testAtomicDelete() throws Exception {
13 years, 2 months