teiid SVN: r2800 - in trunk: engine/src/main/java/org/teiid/common/buffer and 8 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2010-12-23 17:11:01 -0500 (Thu, 23 Dec 2010)
New Revision: 2800
Added:
trunk/engine/src/test/java/org/teiid/common/buffer/TestLobManager.java
Modified:
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/engine/src/main/java/org/teiid/common/buffer/BatchManager.java
trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java
trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java
trunk/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java
trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.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/SessionAwareCache.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/common/buffer/TestTupleBuffer.java
trunk/engine/src/test/java/org/teiid/common/buffer/impl/TestFileStorageManager.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestCachedResults.java
trunk/engine/src/test/java/org/teiid/query/sql/lang/TestQuery.java
Log:
TEIID-1227: adding support to cache lob values in the resultset to disk and releasing the lob references kept to release the connections.
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-23 22:11:01 UTC (rev 2800)
@@ -39,6 +39,7 @@
be used in aggregation or joins and the optimizer will take advantage of the partitioning information. For example, when a partitioned union is joined against another partitioned union, the optimizer will reorganize the join of unions into a union of joins.
<LI><B>Delegate Translator</B> - A new translator added that is capable of delegating all the calls to another configured translator.
<LI><B>JDBC Reauthentication</B> - Teiid connections (defined by the org.teiid.jdbc.TeiidConnection interface) now support the changeUser method to reauthenticate a given connection.
+ <LI><B>Lob Caching</B> - Lobs are allowed to cache to disk as part of ResultSet caching. Distributed lob caching is not allowed.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/BatchManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/BatchManager.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/BatchManager.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -38,4 +38,5 @@
void remove();
+ FileStore createStorage(String prefix);
}
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -202,23 +202,38 @@
protected abstract void removeDirect();
- public InputStream createInputStream(final long start) {
+ public InputStream createInputStream(final long start, final long length) {
return new InputStream() {
private long offset = start;
+ private long streamLength = length;
@Override
public int read() throws IOException {
- throw new UnsupportedOperationException("buffered reading must be used"); //$NON-NLS-1$
+ byte[] buffer = new byte[1];
+ int read = read(buffer, 0, 1);
+ if (read == -1) {
+ return -1;
+ }
+ return buffer[0];
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
try {
- int bytes = FileStore.this.read(offset, b, off, len);
- if (bytes != -1) {
- this.offset += bytes;
+ if (this.streamLength != -1 && len > this.streamLength) {
+ len = (int)this.streamLength;
}
- return bytes;
+ if (this.streamLength == -1 || this.streamLength > 0) {
+ int bytes = FileStore.this.read(offset, b, off, len);
+ if (bytes != -1) {
+ this.offset += bytes;
+ if (this.streamLength != -1) {
+ this.streamLength -= bytes;
+ }
+ }
+ return bytes;
+ }
+ return -1;
} catch (TeiidComponentException e) {
throw new IOException(e);
}
@@ -226,6 +241,10 @@
};
}
+ public InputStream createInputStream(final long start) {
+ return createInputStream(start, -1);
+ }
+
public OutputStream createOutputStream() {
return new OutputStream() {
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -22,15 +22,33 @@
package org.teiid.common.buffer;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.types.BlobImpl;
+import org.teiid.core.types.BlobType;
+import org.teiid.core.types.ClobImpl;
+import org.teiid.core.types.ClobType;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.InputStreamFactory;
+import org.teiid.core.types.SQLXMLImpl;
import org.teiid.core.types.Streamable;
+import org.teiid.core.types.XMLType;
import org.teiid.query.QueryPlugin;
+import org.teiid.query.processor.xml.XMLUtil.FileStoreInputStreamFactory;
import org.teiid.query.sql.symbol.Expression;
/**
@@ -38,9 +56,10 @@
* TODO: for temp tables we may need to have a copy by value management strategy
*/
public class LobManager {
+ private static final int IO_BUFFER_SIZE = 1 << 14;
+ private Map<String, Streamable<?>> lobReferences = new ConcurrentHashMap<String, Streamable<?>>();
+ private Map<String, Streamable<?>> lobFilestores = new ConcurrentHashMap<String, Streamable<?>>();
- private Map<String, Streamable<?>> lobReferences = new ConcurrentHashMap<String, Streamable<?>>();
-
public void updateReferences(int[] lobIndexes, List<?> tuple)
throws TeiidComponentException {
for (int i = 0; i < lobIndexes.length; i++) {
@@ -63,14 +82,20 @@
if (this.lobReferences != null) {
lob = this.lobReferences.get(id);
}
+
if (lob == null) {
+ lob = this.lobFilestores.get(id);
+ }
+
+ if (lob == null) {
throw new TeiidComponentException(QueryPlugin.Util.getString("ProcessWorker.wrongdata")); //$NON-NLS-1$
}
return lob;
}
-
+
public void clear() {
this.lobReferences.clear();
+ this.lobFilestores.clear();
}
public static int[] getLobIndexes(List expressions) {
@@ -91,4 +116,108 @@
return Arrays.copyOf(result, resultIndex);
}
+ public Collection<Streamable<?>> getLobReferences(){
+ return lobReferences.values();
+ }
+
+ public void persist(FileStore lobStore) throws TeiidComponentException {
+ ArrayList<Streamable<?>> lobs = new ArrayList<Streamable<?>>(this.lobReferences.values());
+ for (Streamable<?> lob:lobs) {
+ persist(lob.getReferenceStreamId(), lobStore);
+ }
+ }
+
+ public Streamable<?> persist(String id, FileStore fs) throws TeiidComponentException {
+ Streamable<?> persistedLob = this.lobFilestores.get(id);
+ if (persistedLob == null) {
+ Streamable<?> lobReference = this.lobReferences.get(id);
+ if (lobReference == null) {
+ throw new TeiidComponentException(QueryPlugin.Util.getString("ProcessWorker.wrongdata")); //$NON-NLS-1$
+ }
+
+ persistedLob = persistLob(lobReference, fs);
+ synchronized (this) {
+ this.lobFilestores.put(id, persistedLob);
+ this.lobReferences.remove(id);
+ }
+ }
+ return persistedLob;
+ }
+
+ private Streamable<?> persistLob(final Streamable<?> lob, final FileStore store) throws TeiidComponentException {
+ long offset = store.getLength();
+ int length = 0;
+ Streamable<?> persistedLob;
+
+ // if this is XML and already saved to disk just return
+ if (lob.getReference() instanceof SQLXMLImpl) {
+ try {
+ SQLXMLImpl xml = (SQLXMLImpl)lob.getReference();
+ InputStreamFactory isf = xml.getStreamFactory();
+ if (isf instanceof FileStoreInputStreamFactory) {
+ return lob;
+ }
+ } catch (SQLException e) {
+ // go through regular persistence.
+ }
+ }
+
+ // stream the contents of lob into file store.
+ byte[] bytes = new byte[102400]; // 100k
+ try {
+ InputStreamFactory isf = new InputStreamFactory() {
+ @Override
+ public InputStream getInputStream() throws IOException {
+ if (lob instanceof BlobType) {
+ return new BlobInputStreamFactory((Blob)lob).getInputStream();
+ }
+ else if (lob instanceof ClobType) {
+ return new ClobInputStreamFactory((Clob)lob).getInputStream();
+ }
+ return new SQLXMLInputStreamFactory((SQLXML)lob).getInputStream();
+ }
+ };
+ InputStream is = isf.getInputStream();
+ OutputStream fsos = new BufferedOutputStream(store.createOutputStream(), IO_BUFFER_SIZE);
+ while(true) {
+ int read = is.read(bytes, 0, 102400);
+ if (read == -1) {
+ break;
+ }
+ length += read;
+ fsos.write(bytes, 0, read);
+ }
+ fsos.close();
+ is.close();
+ } catch (IOException e) {
+ throw new TeiidComponentException(e);
+ }
+
+ // re-construct the new lobs based on the file store
+ final long lobOffset = offset;
+ final int lobLength = length;
+ InputStreamFactory isf = new InputStreamFactory() {
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return store.createInputStream(lobOffset, lobLength);
+ }
+ };
+
+ try {
+ if (lob instanceof BlobType) {
+ persistedLob = new BlobType(new BlobImpl(isf));
+ }
+ else if (lob instanceof ClobType) {
+ persistedLob = new ClobType(new ClobImpl(isf, ((ClobType)lob).length()));
+ }
+ else {
+ persistedLob = new XMLType(new SQLXMLImpl(isf));
+ ((XMLType)persistedLob).setEncoding(((XMLType)lob).getEncoding());
+ ((XMLType)persistedLob).setType(((XMLType)lob).getType());
+ }
+ } catch (SQLException e) {
+ throw new TeiidComponentException(e);
+ }
+ return persistedLob;
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -77,6 +77,7 @@
private LobManager lobManager;
private int[] lobIndexes;
private String uuid;
+ private FileStore lobStore;
public TupleBuffer(BatchManager manager, String id, List<?> schema, int[] lobIndexes, int batchSize) {
this.manager = manager;
@@ -86,6 +87,8 @@
this.lobIndexes = lobIndexes;
if (this.lobIndexes != null) {
this.lobManager = new LobManager();
+ this.lobStore = this.manager.createStorage("_lobs"); //$NON-NLS-1$
+ this.lobStore.setCleanupReference(this);
}
this.batchSize = batchSize;
}
@@ -155,6 +158,13 @@
this.batches.clear();
}
+ public void persistLobs() throws TeiidComponentException {
+ if (this.lobManager != null) {
+ saveBatch(true, true);
+ this.lobManager.persist(this.lobStore);
+ }
+ }
+
/**
* Force the persistence of any rows held in memory.
* @throws TeiidComponentException
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 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -33,6 +33,7 @@
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
@@ -60,6 +61,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.Streamable;
import org.teiid.core.util.Assertion;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
@@ -104,6 +106,10 @@
this.store.setCleanupReference(this);
this.lobIndexes = lobIndexes;
}
+
+ public FileStore createStorage(String prefix) {
+ return createFileStore(id+prefix);
+ }
@Override
public ManagedBatch createManagedBatch(TupleBatch batch, boolean softCache)
@@ -312,6 +318,10 @@
if (lobManager != null) {
for (List<?> tuple : batch.getTuples()) {
lobManager.updateReferences(batchManager.lobIndexes, tuple);
+ Collection<Streamable<?>> lobs = lobManager.getLobReferences();
+ for(Streamable<?> lob: lobs) {
+ lobManager.persist(lob.getReferenceStreamId(), batchManager.store);
+ }
}
}
synchronized (batchManager.store) {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -63,6 +63,7 @@
private int batchSize;
private String uuid;
private int rowCount;
+ private boolean hasLobs;
public String getId() {
return this.uuid;
@@ -86,6 +87,7 @@
this.types = TupleBuffer.getTypeNames(results.getSchema());
this.rowCount = results.getRowCount();
this.uuid = results.getId();
+ this.hasLobs = results.isLobs();
}
public void setCommand(Command command) {
@@ -120,6 +122,9 @@
public synchronized boolean restore(Cache cache, BufferManager bufferManager) {
try {
if (this.results == null) {
+ if (this.hasLobs) {
+ return false;
+ }
List<ElementSymbol> schema = new ArrayList<ElementSymbol>(types.length);
for (String type : types) {
ElementSymbol es = new ElementSymbol("x"); //$NON-NLS-1$
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 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -558,6 +558,7 @@
private void clearResultSetCache(String vdbName, int version) {
//clear cache in server
if(rsCache != null){
+ LogManager.logInfo(LogConstants.CTX_DQP, QueryPlugin.Util.getString("DQPCore.clearing_resultset_cache", vdbName, version)); //$NON-NLS-1$
rsCache.clearForVDB(vdbName, version);
}
}
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 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -296,6 +296,14 @@
resultsBuffer.remove();
}
+ try {
+ if (cid != null && this.resultsBuffer.isLobs()) {
+ 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();
}
@@ -377,7 +385,7 @@
collector = new BatchCollector(processor, resultsBuffer) {
protected void flushBatchDirect(TupleBatch batch, boolean add) throws TeiidComponentException,TeiidProcessingException {
boolean added = false;
- if (cid != null || resultsBuffer.isLobs()) {
+ if (cid != null) {
super.flushBatchDirect(batch, add);
added = true;
}
@@ -391,7 +399,7 @@
cr.setAnalysisRecord(analysisRecord);
cr.setResults(resultsBuffer);
- if (originalCommand.getCacheHint() != null && originalCommand.getCacheHint().getDeterminism() != null) {
+ if (originalCommand.getCacheHint() != null && originalCommand.getCacheHint().getDeterminism() != null) {
determinismLevel = originalCommand.getCacheHint().getDeterminism();
LogManager.logTrace(LogConstants.CTX_DQP, new Object[] { "Cache hint modified the query determinism from ",processor.getContext().getDeterminismLevel(), " to ", determinismLevel }); //$NON-NLS-1$ //$NON-NLS-2$
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -253,7 +253,7 @@
}
Class<?> type = DataTypeManager.determineDataTypeClass(obj);
- if (DataTypeManager.isLOB(type) || type == DataTypeManager.DefaultDataClasses.OBJECT) {
+ if (type == DataTypeManager.DefaultDataClasses.OBJECT) {
return false;
}
this.parameters.add((Serializable)obj);
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -431,7 +431,7 @@
public static boolean areResultsCachable(Collection<? extends SingleElementSymbol> projectedSymbols) {
for (SingleElementSymbol projectedSymbol : projectedSymbols) {
- if(DataTypeManager.isLOB(projectedSymbol.getType()) || projectedSymbol.getType() == DataTypeManager.DefaultDataClasses.OBJECT) {
+ if(projectedSymbol.getType() == DataTypeManager.DefaultDataClasses.OBJECT) {
return false;
}
}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2010-12-23 22:11:01 UTC (rev 2800)
@@ -830,6 +830,7 @@
DQPCore.Unable_to_load_metadata_for_VDB_name__{0},_version__{1}=Unable to load metadata for VDB name= {0}, version= {1}
DQPCore.Unknown_query_metadata_exception_while_registering_query__{0}.=Unknown query metadata exception while registering query: {0}.
DQPCore.Clearing_prepared_plan_cache=Clearing prepared plan cache
+DQPCore.clearing_resultset_cache=Clearing the resultset cache for vdb {0}.{1}
DQPCore.The_request_has_been_closed.=The request {0} has been closed.
DQPCore.The_atomic_request_has_been_cancelled=The atomic request {0} has been canceled.
DQPCore.failed_to_cancel=Failed to Cancel request, as request already finished processing
@@ -888,6 +889,7 @@
RequestWorkItem.cache_nondeterministic=Caching command "{0}" at a session level, but less deterministic functions were evaluated.
not_found_cache=Results not found in cache
+failed_to_cache=Failed to store the result set contents to disk.
failed_to_unwrap_connection=Failed to unwrap the source connection.
connection_factory_not_found=Failed to find the Connection Factory with JNDI name {0}. Please check the name or deploy the Connection Factory with specified name.
Added: trunk/engine/src/test/java/org/teiid/common/buffer/TestLobManager.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/buffer/TestLobManager.java (rev 0)
+++ trunk/engine/src/test/java/org/teiid/common/buffer/TestLobManager.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -0,0 +1,98 @@
+/*
+ * 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.common.buffer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.teiid.common.buffer.impl.BufferManagerImpl;
+import org.teiid.core.types.BlobImpl;
+import org.teiid.core.types.BlobType;
+import org.teiid.core.types.ClobImpl;
+import org.teiid.core.types.ClobType;
+import org.teiid.core.types.InputStreamFactory;
+import org.teiid.core.types.Streamable;
+import org.teiid.core.util.ReaderInputStream;
+
+@SuppressWarnings("nls")
+public class TestLobManager {
+
+ @Test
+ public void testLobPeristence() throws Exception{
+
+ BufferManagerImpl buffMgr = BufferManagerFactory.createBufferManager();
+ FileStore fs = buffMgr.createFileStore("temp");
+
+ ClobType clob = new ClobType(new ClobImpl(new InputStreamFactory() {
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ReaderInputStream(new StringReader("Clob contents One"), Charset.forName(Streamable.ENCODING));
+ }
+
+ }, -1));
+
+ BlobType blob = new BlobType(new BlobImpl(new InputStreamFactory() {
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ReaderInputStream(new StringReader("Blob contents Two"), Charset.forName(Streamable.ENCODING));
+ }
+
+ }));
+
+ LobManager lobManager = new LobManager();
+ lobManager.updateReferences(new int[] {0,1}, Arrays.asList(clob, blob));
+ lobManager.persist(fs);
+
+ Streamable<?>lob = lobManager.getLobReference(clob.getReferenceStreamId());
+ assertTrue(lob.getClass().isAssignableFrom(ClobType.class));
+ ClobType clobRead = (ClobType)lob;
+ assertEquals(ClobType.getString(clob), ClobType.getString(clobRead));
+ assertTrue(clobRead.length() != -1);
+
+ lob = lobManager.getLobReference(blob.getReferenceStreamId());
+ assertTrue(lob.getClass().isAssignableFrom(BlobType.class));
+ BlobType blobRead = (BlobType)lob;
+ assertTrue(Arrays.equals(read(blob.getBinaryStream()), read(blobRead.getBinaryStream())));
+
+ }
+
+ private byte[] read(InputStream in) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] bytes = new byte[100];
+ while (true) {
+ int c = in.read(bytes, 0, 100);
+ if (c == -1) {
+ break;
+ }
+ out.write(c);
+ }
+ return out.toByteArray();
+ }
+}
Property changes on: trunk/engine/src/test/java/org/teiid/common/buffer/TestLobManager.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/test/java/org/teiid/common/buffer/TestTupleBuffer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/buffer/TestTupleBuffer.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/test/java/org/teiid/common/buffer/TestTupleBuffer.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -30,6 +30,7 @@
import javax.sql.rowset.serial.SerialClob;
import org.junit.Test;
+import org.mockito.Mockito;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.ClobType;
import org.teiid.core.types.DataTypeManager;
@@ -61,6 +62,11 @@
}
};
}
+
+ @Override
+ public FileStore createStorage(String prefix) {
+ return Mockito.mock(FileStore.class);
+ }
}
@Test public void testForwardOnly() throws Exception {
Modified: trunk/engine/src/test/java/org/teiid/common/buffer/impl/TestFileStorageManager.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/buffer/impl/TestFileStorageManager.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/test/java/org/teiid/common/buffer/impl/TestFileStorageManager.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -25,6 +25,8 @@
import static org.junit.Assert.*;
import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Map;
@@ -36,6 +38,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.util.UnitTestUtil;
+@SuppressWarnings("nls")
public class TestFileStorageManager {
public FileStorageManager getStorageManager(Integer maxFileSize, Integer openFiles, String dir) throws TeiidComponentException {
@@ -111,4 +114,37 @@
assertTrue(Arrays.equals(bytes, bytesRead));
}
+
+ @Test public void testWritingMultipleFiles() throws Exception {
+ FileStorageManager sm = getStorageManager(1024, null, null);
+ String tsID = "0"; //$NON-NLS-1$
+ // Add one batch
+ FileStore store = sm.createFileStore(tsID);
+ String contentOrig = new String("some file content this will stored in same tmp file with another");
+ OutputStream out = store.createOutputStream();
+ out.write(contentOrig.getBytes(), 0, contentOrig.getBytes().length);
+ out.close();
+
+ out = store.createOutputStream();
+ long start = store.getLength();
+ byte[] bytesOrig = new byte[2048];
+ r.nextBytes(bytesOrig);
+ out.write(bytesOrig, 0, 2048);
+
+ byte[] readContent = new byte[2048];
+ InputStream in = store.createInputStream(0, contentOrig.getBytes().length);
+ int c = in.read(readContent, 0, 3000);
+ assertEquals(contentOrig, new String(readContent, 0, c));
+ c = in.read(readContent, 0, 3000);
+ assertEquals(-1, c);
+ in.close();
+
+ in = store.createInputStream(start, 2048);
+ c = in.read(readContent, 0, 3000);
+ assertTrue(Arrays.equals(bytesOrig, readContent));
+ c = in.read(readContent, 0, 3000);
+ assertEquals(-1, c);
+ in.close();
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestCachedResults.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestCachedResults.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestCachedResults.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -32,10 +32,12 @@
import java.util.List;
import org.junit.Test;
+import org.mockito.Mockito;
import org.teiid.cache.Cache;
import org.teiid.cache.DefaultCache;
import org.teiid.common.buffer.BatchManager;
import org.teiid.common.buffer.BufferManager;
+import org.teiid.common.buffer.FileStore;
import org.teiid.common.buffer.TupleBatch;
import org.teiid.common.buffer.TupleBuffer;
import org.teiid.core.TeiidComponentException;
@@ -70,6 +72,11 @@
}
};
}
+
+ @Override
+ public FileStore createStorage(String prefix) {
+ return Mockito.mock(FileStore.class);
+ }
}
@Test
Modified: trunk/engine/src/test/java/org/teiid/query/sql/lang/TestQuery.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/lang/TestQuery.java 2010-12-23 21:35:33 UTC (rev 2799)
+++ trunk/engine/src/test/java/org/teiid/query/sql/lang/TestQuery.java 2010-12-23 22:11:01 UTC (rev 2800)
@@ -135,21 +135,21 @@
select.addSymbol(column);
query.setSelect(select);
query.setFrom(from);
- assertTrue(!query.areResultsCachable());
+ assertTrue(query.areResultsCachable());
select = new Select();
column = new ElementSymbol("y");//$NON-NLS-1$
column.setType(ClobType.class);
select.addSymbol(column);
query.setSelect(select);
query.setFrom(from);
- assertTrue(!query.areResultsCachable());
+ assertTrue(query.areResultsCachable());
select = new Select();
column = new ElementSymbol("y");//$NON-NLS-1$
column.setType(XMLType.class);
select.addSymbol(column);
query.setSelect(select);
query.setFrom(from);
- assertTrue(!query.areResultsCachable());
+ assertTrue(query.areResultsCachable());
}
public void testClone2() {
14 years
teiid SVN: r2799 - in branches/7.1.x/connectors/translator-salesforce/src: test/java/org/teiid/translator/salesforce/execution/visitors and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2010-12-23 16:35:33 -0500 (Thu, 23 Dec 2010)
New Revision: 2799
Modified:
branches/7.1.x/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/Util.java
branches/7.1.x/connectors/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java
Log:
TEIID-1406 fixing the timestamp format to not include the Z character
Modified: branches/7.1.x/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/Util.java
===================================================================
--- branches/7.1.x/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/Util.java 2010-12-23 20:57:51 UTC (rev 2798)
+++ branches/7.1.x/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/Util.java 2010-12-23 21:35:33 UTC (rev 2799)
@@ -57,7 +57,7 @@
}
public static SimpleDateFormat getSalesforceDateTimeFormat() {
- return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); //$NON-NLS-1$
+ return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); //$NON-NLS-1$
}
public static SimpleDateFormat getTimeZoneOffsetFormat() {
Modified: branches/7.1.x/connectors/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java
===================================================================
--- branches/7.1.x/connectors/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java 2010-12-23 20:57:51 UTC (rev 2798)
+++ branches/7.1.x/connectors/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java 2010-12-23 21:35:33 UTC (rev 2799)
@@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.List;
+import java.util.TimeZone;
import org.junit.Test;
import org.mockito.Mockito;
@@ -45,8 +46,6 @@
import org.teiid.translator.salesforce.Constants;
import org.teiid.translator.salesforce.SalesforceConnection;
import org.teiid.translator.salesforce.execution.QueryExecutionImpl;
-import org.teiid.translator.salesforce.execution.visitors.JoinQueryVisitor;
-import org.teiid.translator.salesforce.execution.visitors.SelectVisitor;
@SuppressWarnings("nls")
public class TestVisitors {
@@ -87,16 +86,16 @@
contactTable.setProperty("Supports Query", Boolean.TRUE.toString()); //$NON-NLS-1$
// Create Contact Columns
String[] elemNames = new String[] {
- "ContactID", "Name", "AccountId" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "ContactID", "Name", "AccountId", "InitialContact" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
};
String[] elemTypes = new String[] {
- DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING
+ DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.TIMESTAMP
};
List<Column> contactCols = RealMetadataFactory.createElements(contactTable, elemNames, elemTypes);
// Set name in source on each column
String[] contactNameInSource = new String[] {
- "id", "ContactName", "accountid" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "id", "ContactName", "accountid", "InitialContact" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
};
for(int i=0; i<2; i++) {
Column obj = contactCols.get(i);
@@ -184,5 +183,17 @@
qei.execute();
Mockito.verify(sfc).retrieve("Account.id, Account.AccountName", "Account", Arrays.asList("bar"));
}
+
+ @Test public void testDateTimeFormating() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT-06:00"));
+ try {
+ Select command = (Select)translationUtility.parseCommand("select name from contacts where initialcontact = {ts'2003-03-11 11:42:10.5'}"); //$NON-NLS-1$
+ SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Contact.ContactName FROM Contact WHERE Contact.InitialContact = 2003-03-11T11:42:10.500-06:00", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ } finally {
+ TimeZone.setDefault(null);
+ }
+ }
}
14 years
teiid SVN: r2798 - in trunk: documentation/reference/src/main/docbook/en-US/content and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2010-12-23 15:57:51 -0500 (Thu, 23 Dec 2010)
New Revision: 2798
Modified:
trunk/connectors/translator-delegate/
trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
Log:
TEIID-1330 updating the delegation logic
Property changes on: trunk/connectors/translator-delegate
___________________________________________________________________
Name: svn:ignore
- .project
.classpath
.settings
+ .project
.classpath
.settings
target
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2010-12-23 20:46:42 UTC (rev 2797)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2010-12-23 20:57:51 UTC (rev 2798)
@@ -1014,10 +1014,8 @@
<para>
The Delegate translator, known by the type name <emphasis>delegate</emphasis>,
provides way to delegate all the translator calls to yet another translator whoose name is supplied. This does not provide
- any functionality on its own, other than delegation. This translator can be used to intercept the calls to the user
- supplied translator and modify them as they see fit. Another advantage of this translator is, user is not required to
- package their translator as precribed in JAR file as shown in the developer's guide, all user need to do
- is to make sure the supplied class is availble in classpath that is used by 'delegate' translator.
+ any functionality on its own, other than delegation. This translator can be used a base class to intercept the calls to the user
+ supplied translator and modify them as they see fit.
</para>
<table>
@@ -1035,8 +1033,8 @@
</thead>
<tbody>
<row>
- <entry>delegateClassName</entry>
- <entry>User defined ExcutionFactory class name, to be delegated to</entry>
+ <entry>delegateName</entry>
+ <entry>Translator instance to delegate to</entry>
<entry></entry>
</row>
</tbody>
14 years
teiid SVN: r2797 - in trunk: connectors/translator-delegate and 4 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2010-12-23 15:46:42 -0500 (Thu, 23 Dec 2010)
New Revision: 2797
Added:
trunk/api/src/main/java/org/teiid/translator/DelegatingExecutionFactory.java
trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/BaseDelegatingExecutionFactory.java
Removed:
trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java
trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/
trunk/connectors/translator-delegate/target/
Modified:
trunk/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
Log:
TEIID-1330 updating the delegation logic
Added: trunk/api/src/main/java/org/teiid/translator/DelegatingExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/DelegatingExecutionFactory.java (rev 0)
+++ trunk/api/src/main/java/org/teiid/translator/DelegatingExecutionFactory.java 2010-12-23 20:46:42 UTC (rev 2797)
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+public interface DelegatingExecutionFactory<F, C> {
+
+ String getDelegateName();
+
+ void setDelegate(ExecutionFactory<F, C> delegate);
+}
\ No newline at end of file
Property changes on: trunk/api/src/main/java/org/teiid/translator/DelegatingExecutionFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/BaseDelegatingExecutionFactory.java (from rev 2795, trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java)
===================================================================
--- trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/BaseDelegatingExecutionFactory.java (rev 0)
+++ trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/BaseDelegatingExecutionFactory.java 2010-12-23 20:46:42 UTC (rev 2797)
@@ -0,0 +1,405 @@
+/*
+ * 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.delegate;
+
+import java.util.List;
+
+import org.teiid.language.Call;
+import org.teiid.language.Command;
+import org.teiid.language.LanguageFactory;
+import org.teiid.language.QueryExpression;
+import org.teiid.metadata.FunctionMethod;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.DelegatingExecutionFactory;
+import org.teiid.translator.Execution;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ExecutionFactory;
+import org.teiid.translator.ProcedureExecution;
+import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.Translator;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TranslatorProperty;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.UpdateExecution;
+
+/**
+ * Delegate translator. User can define a {@link ExecutionFactory} of their own and have this translator
+ * delegate all the calls to that class. This will help user to avoid packing their translator in the required
+ * jar packaging and lets the user intercept the calls for their needs. Please note that your 'vdb.xml' file contains
+ * the following xml fragment to configure this translator to delegate calls to custom translator.
+ * <pre>
+ * {@code
+ <translator type="delegate" name="my-translator" description="custom translator">
+ <property value="delegateName" name="name of the delegate instance"/>
+ </translator>
+ }
+ * </pre>
+ *
+ */
+@Translator(name="delegate", description="A translator that acts as delegator to the another translator")
+public class BaseDelegatingExecutionFactory<F, C> extends ExecutionFactory<F, C> implements DelegatingExecutionFactory<F, C> {
+
+ private String delegateName;
+ private ExecutionFactory<F, C> delegate;
+
+ /**
+ * For testing only
+ */
+ ExecutionFactory<F, C> getDelegate() {
+ return this.delegate;
+ }
+
+ public void setDelegate(ExecutionFactory<F, C> delegate) {
+ this.delegate = delegate;
+ }
+
+ @TranslatorProperty(display="Delegate name", required = true)
+ public String getDelegateName() {
+ return this.delegateName;
+ }
+
+ public void setDelegateName(String delegateName) {
+ this.delegateName = delegateName;
+ }
+
+ @Override
+ public void start() throws TranslatorException {
+ this.delegate.start();
+ }
+
+ @Override
+ public boolean areLobsUsableAfterClose() {
+ return delegate.areLobsUsableAfterClose();
+ }
+ @Override
+ public void closeConnection(C connection, F factory) {
+ delegate.closeConnection(connection, factory);
+ }
+ @Override
+ public Execution createExecution(Command command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ C connection) throws TranslatorException {
+ return delegate.createExecution(command, executionContext, metadata,
+ connection);
+ }
+ @Override
+ public ProcedureExecution createProcedureExecution(Call command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ C connection) throws TranslatorException {
+ return delegate.createProcedureExecution(command, executionContext,
+ metadata, connection);
+ }
+ @Override
+ public ResultSetExecution createResultSetExecution(QueryExpression command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ C connection) throws TranslatorException {
+ return delegate.createResultSetExecution(command, executionContext,
+ metadata, connection);
+ }
+ @Override
+ public UpdateExecution createUpdateExecution(Command command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ C connection) throws TranslatorException {
+ return delegate.createUpdateExecution(command, executionContext,
+ metadata, connection);
+ }
+ @Override
+ public C getConnection(F factory) throws TranslatorException {
+ return delegate.getConnection(factory);
+ }
+ @Override
+ public NullOrder getDefaultNullOrder() {
+ return delegate.getDefaultNullOrder();
+ }
+ @Override
+ public LanguageFactory getLanguageFactory() {
+ return delegate.getLanguageFactory();
+ }
+ @Override
+ public int getMaxFromGroups() {
+ return delegate.getMaxFromGroups();
+ }
+ @Override
+ public int getMaxInCriteriaSize() {
+ return delegate.getMaxInCriteriaSize();
+ }
+ @Override
+ public void getMetadata(MetadataFactory metadataFactory, C conn)
+ throws TranslatorException {
+ delegate.getMetadata(metadataFactory, conn);
+ }
+ @Override
+ public List<FunctionMethod> getPushDownFunctions() {
+ return delegate.getPushDownFunctions();
+ }
+ @Override
+ public List<String> getSupportedFunctions() {
+ return delegate.getSupportedFunctions();
+ }
+ @Override
+ public TypeFacility getTypeFacility() {
+ return delegate.getTypeFacility();
+ }
+ @Override
+ public boolean isImmutable() {
+ return delegate.isImmutable();
+ }
+ @Override
+ public boolean isSourceRequired() {
+ return delegate.isSourceRequired();
+ }
+ @Override
+ public void setImmutable(boolean arg0) {
+ delegate.setImmutable(arg0);
+ }
+ @Override
+ public void setRequiresCriteria(boolean requiresCriteria) {
+ delegate.setRequiresCriteria(requiresCriteria);
+ }
+ @Override
+ public void setSourceRequired(boolean value) {
+ delegate.setSourceRequired(value);
+ }
+ @Override
+ public void setSupportedJoinCriteria(
+ SupportedJoinCriteria supportedJoinCriteria) {
+ delegate.setSupportedJoinCriteria(supportedJoinCriteria);
+ }
+ @Override
+ public void setSupportsFullOuterJoins(boolean supportsFullOuterJoins) {
+ delegate.setSupportsFullOuterJoins(supportsFullOuterJoins);
+ }
+ @Override
+ public void setSupportsInnerJoins(boolean supportsInnerJoins) {
+ delegate.setSupportsInnerJoins(supportsInnerJoins);
+ }
+ @Override
+ public void setSupportsOrderBy(boolean supportsOrderBy) {
+ delegate.setSupportsOrderBy(supportsOrderBy);
+ }
+ @Override
+ public void setSupportsOuterJoins(boolean supportsOuterJoins) {
+ delegate.setSupportsOuterJoins(supportsOuterJoins);
+ }
+ @Override
+ public void setSupportsSelectDistinct(boolean supportsSelectDistinct) {
+ delegate.setSupportsSelectDistinct(supportsSelectDistinct);
+ }
+ @Override
+ public boolean supportsAggregatesAvg() {
+ return delegate.supportsAggregatesAvg();
+ }
+ @Override
+ public boolean supportsAggregatesCount() {
+ return delegate.supportsAggregatesCount();
+ }
+ @Override
+ public boolean supportsAggregatesCountStar() {
+ return delegate.supportsAggregatesCountStar();
+ }
+ @Override
+ public boolean supportsAggregatesDistinct() {
+ return delegate.supportsAggregatesDistinct();
+ }
+ @Override
+ public boolean supportsAggregatesEnhancedNumeric() {
+ return delegate.supportsAggregatesEnhancedNumeric();
+ }
+ @Override
+ public boolean supportsAggregatesMax() {
+ return delegate.supportsAggregatesMax();
+ }
+ @Override
+ public boolean supportsAggregatesMin() {
+ return delegate.supportsAggregatesMin();
+ }
+ @Override
+ public boolean supportsAggregatesSum() {
+ return delegate.supportsAggregatesSum();
+ }
+ @Override
+ public boolean supportsAliasedTable() {
+ return delegate.supportsAliasedTable();
+ }
+ @Override
+ public boolean supportsBatchedUpdates() {
+ return delegate.supportsBatchedUpdates();
+ }
+ @Override
+ public boolean supportsBetweenCriteria() {
+ return delegate.supportsBetweenCriteria();
+ }
+ @Override
+ public boolean supportsBulkUpdate() {
+ return delegate.supportsBulkUpdate();
+ }
+ @Override
+ public boolean supportsCaseExpressions() {
+ return delegate.supportsCaseExpressions();
+ }
+ @Override
+ public boolean supportsCommonTableExpressions() {
+ return delegate.supportsCommonTableExpressions();
+ }
+ @Override
+ public boolean supportsCompareCriteriaEquals() {
+ return delegate.supportsCompareCriteriaEquals();
+ }
+ @Override
+ public boolean supportsCompareCriteriaOrdered() {
+ return delegate.supportsCompareCriteriaOrdered();
+ }
+ @Override
+ public boolean supportsCorrelatedSubqueries() {
+ return delegate.supportsCorrelatedSubqueries();
+ }
+ @Override
+ public boolean supportsExcept() {
+ return delegate.supportsExcept();
+ }
+ @Override
+ public boolean supportsExistsCriteria() {
+ return delegate.supportsExistsCriteria();
+ }
+ @Override
+ public boolean supportsFunctionsInGroupBy() {
+ return delegate.supportsFunctionsInGroupBy();
+ }
+ @Override
+ public boolean supportsGroupBy() {
+ return delegate.supportsGroupBy();
+ }
+ @Override
+ public boolean supportsHaving() {
+ return delegate.supportsHaving();
+ }
+ @Override
+ public boolean supportsInCriteria() {
+ return delegate.supportsInCriteria();
+ }
+ @Override
+ public boolean supportsInCriteriaSubquery() {
+ return delegate.supportsInCriteriaSubquery();
+ }
+ @Override
+ public boolean supportsInlineViews() {
+ return delegate.supportsInlineViews();
+ }
+ @Override
+ public boolean supportsInsertWithIterator() {
+ return delegate.supportsInsertWithIterator();
+ }
+ @Override
+ public boolean supportsInsertWithQueryExpression() {
+ return delegate.supportsInsertWithQueryExpression();
+ }
+ @Override
+ public boolean supportsIntersect() {
+ return delegate.supportsIntersect();
+ }
+ @Override
+ public boolean supportsIsNullCriteria() {
+ return delegate.supportsIsNullCriteria();
+ }
+ @Override
+ public boolean supportsLikeCriteria() {
+ return delegate.supportsLikeCriteria();
+ }
+ @Override
+ public boolean supportsLikeCriteriaEscapeCharacter() {
+ return delegate.supportsLikeCriteriaEscapeCharacter();
+ }
+ @Override
+ public boolean supportsNotCriteria() {
+ return delegate.supportsNotCriteria();
+ }
+ @Override
+ public boolean supportsOrCriteria() {
+ return delegate.supportsOrCriteria();
+ }
+ @Override
+ public boolean supportsOrderByNullOrdering() {
+ return delegate.supportsOrderByNullOrdering();
+ }
+ @Override
+ public boolean supportsOrderByUnrelated() {
+ return delegate.supportsOrderByUnrelated();
+ }
+ @Override
+ public boolean supportsQuantifiedCompareCriteriaAll() {
+ return delegate.supportsQuantifiedCompareCriteriaAll();
+ }
+ @Override
+ public boolean supportsQuantifiedCompareCriteriaSome() {
+ return delegate.supportsQuantifiedCompareCriteriaSome();
+ }
+ @Override
+ public boolean supportsRowLimit() {
+ return delegate.supportsRowLimit();
+ }
+ @Override
+ public boolean supportsRowOffset() {
+ return delegate.supportsRowOffset();
+ }
+ @Override
+ public boolean supportsScalarSubqueries() {
+ return delegate.supportsScalarSubqueries();
+ }
+ @Override
+ public boolean supportsSearchedCaseExpressions() {
+ return delegate.supportsSearchedCaseExpressions();
+ }
+ @Override
+ public boolean supportsSelectExpression() {
+ return delegate.supportsSelectExpression();
+ }
+ @Override
+ public boolean supportsSelfJoins() {
+ return delegate.supportsSelfJoins();
+ }
+ @Override
+ public boolean supportsSetQueryOrderBy() {
+ return delegate.supportsSetQueryOrderBy();
+ }
+ @Override
+ public boolean supportsUnions() {
+ return delegate.supportsUnions();
+ }
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ @Override
+ public boolean useAnsiJoin() {
+ return delegate.useAnsiJoin();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return delegate.equals(obj);
+ }
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+}
Deleted: trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java
===================================================================
--- trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java 2010-12-23 20:05:36 UTC (rev 2796)
+++ trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java 2010-12-23 20:46:42 UTC (rev 2797)
@@ -1,399 +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.translator.delegate;
-
-import java.util.List;
-
-import org.teiid.language.Call;
-import org.teiid.language.Command;
-import org.teiid.language.LanguageFactory;
-import org.teiid.language.QueryExpression;
-import org.teiid.metadata.MetadataFactory;
-import org.teiid.metadata.RuntimeMetadata;
-import org.teiid.translator.Execution;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.ExecutionFactory;
-import org.teiid.translator.ProcedureExecution;
-import org.teiid.translator.ResultSetExecution;
-import org.teiid.translator.Translator;
-import org.teiid.translator.TranslatorException;
-import org.teiid.translator.TranslatorProperty;
-import org.teiid.translator.TypeFacility;
-import org.teiid.translator.UpdateExecution;
-
-/**
- * Delegate translator. User can define a {@link ExecutionFactory} of their own and have this translator
- * delegate all the calls to that class. This will help user to avoid packing their translator in the required
- * jar packaging and lets the user intercept the calls for their needs. Please note that your 'vdb.xml' file contains
- * the following xml fragment to configure this translator to delegate calls to custom translator.
- * <pre>
- * {@code
- <translator type="delegate" name="my-translator" description="custom translator">
- <property value="delegateClassName" name="name of class that implements custom execution factory"/>
- </translator>
- }
- * </pre>
- *
- */
-@Translator(name="delegate", description="A translator that acts as delegator to the another translator")
-public class DelegateExecutionFactory<F, C> extends ExecutionFactory {
-
- private String delegateClassName;
- private ExecutionFactory delegate;
-
- @TranslatorProperty(display="Delegatee class name", required = true)
- public String getDelegateClassName() {
- return this.delegateClassName;
- }
-
- public void setDelegateClassName(String delegateName) {
- this.delegateClassName = delegateName;
- }
-
- /**
- * For testing only
- */
- ExecutionFactory getDelegatee() {
- return this.delegate;
- }
-
- @Override
- public void start() throws TranslatorException {
- this.delegate = getInstance(ExecutionFactory.class, this.delegateClassName,null, null);
- this.delegate.start();
- }
- @Override
- public boolean areLobsUsableAfterClose() {
- return delegate.areLobsUsableAfterClose();
- }
- @Override
- public void closeConnection(Object connection, Object factory) {
- delegate.closeConnection(connection, factory);
- }
- @Override
- public Execution createExecution(Command command,
- ExecutionContext executionContext, RuntimeMetadata metadata,
- Object connection) throws TranslatorException {
- return delegate.createExecution(command, executionContext, metadata,
- connection);
- }
- @Override
- public ProcedureExecution createProcedureExecution(Call command,
- ExecutionContext executionContext, RuntimeMetadata metadata,
- Object connection) throws TranslatorException {
- return delegate.createProcedureExecution(command, executionContext,
- metadata, connection);
- }
- @Override
- public ResultSetExecution createResultSetExecution(QueryExpression command,
- ExecutionContext executionContext, RuntimeMetadata metadata,
- Object connection) throws TranslatorException {
- return delegate.createResultSetExecution(command, executionContext,
- metadata, connection);
- }
- @Override
- public UpdateExecution createUpdateExecution(Command command,
- ExecutionContext executionContext, RuntimeMetadata metadata,
- Object connection) throws TranslatorException {
- return delegate.createUpdateExecution(command, executionContext,
- metadata, connection);
- }
- @Override
- public Object getConnection(Object factory) throws TranslatorException {
- return delegate.getConnection(factory);
- }
- @Override
- public NullOrder getDefaultNullOrder() {
- return delegate.getDefaultNullOrder();
- }
- @Override
- public LanguageFactory getLanguageFactory() {
- return delegate.getLanguageFactory();
- }
- @Override
- public int getMaxFromGroups() {
- return delegate.getMaxFromGroups();
- }
- @Override
- public int getMaxInCriteriaSize() {
- return delegate.getMaxInCriteriaSize();
- }
- @Override
- public void getMetadata(MetadataFactory metadataFactory, Object conn)
- throws TranslatorException {
- delegate.getMetadata(metadataFactory, conn);
- }
- @Override
- public List getPushDownFunctions() {
- return delegate.getPushDownFunctions();
- }
- @Override
- public List getSupportedFunctions() {
- return delegate.getSupportedFunctions();
- }
- @Override
- public TypeFacility getTypeFacility() {
- return delegate.getTypeFacility();
- }
- @Override
- public boolean isImmutable() {
- return delegate.isImmutable();
- }
- @Override
- public boolean isSourceRequired() {
- return delegate.isSourceRequired();
- }
- @Override
- public void setImmutable(boolean arg0) {
- delegate.setImmutable(arg0);
- }
- @Override
- public void setRequiresCriteria(boolean requiresCriteria) {
- delegate.setRequiresCriteria(requiresCriteria);
- }
- @Override
- public void setSourceRequired(boolean value) {
- delegate.setSourceRequired(value);
- }
- @Override
- public void setSupportedJoinCriteria(
- SupportedJoinCriteria supportedJoinCriteria) {
- delegate.setSupportedJoinCriteria(supportedJoinCriteria);
- }
- @Override
- public void setSupportsFullOuterJoins(boolean supportsFullOuterJoins) {
- delegate.setSupportsFullOuterJoins(supportsFullOuterJoins);
- }
- @Override
- public void setSupportsInnerJoins(boolean supportsInnerJoins) {
- delegate.setSupportsInnerJoins(supportsInnerJoins);
- }
- @Override
- public void setSupportsOrderBy(boolean supportsOrderBy) {
- delegate.setSupportsOrderBy(supportsOrderBy);
- }
- @Override
- public void setSupportsOuterJoins(boolean supportsOuterJoins) {
- delegate.setSupportsOuterJoins(supportsOuterJoins);
- }
- @Override
- public void setSupportsSelectDistinct(boolean supportsSelectDistinct) {
- delegate.setSupportsSelectDistinct(supportsSelectDistinct);
- }
- @Override
- public boolean supportsAggregatesAvg() {
- return delegate.supportsAggregatesAvg();
- }
- @Override
- public boolean supportsAggregatesCount() {
- return delegate.supportsAggregatesCount();
- }
- @Override
- public boolean supportsAggregatesCountStar() {
- return delegate.supportsAggregatesCountStar();
- }
- @Override
- public boolean supportsAggregatesDistinct() {
- return delegate.supportsAggregatesDistinct();
- }
- @Override
- public boolean supportsAggregatesEnhancedNumeric() {
- return delegate.supportsAggregatesEnhancedNumeric();
- }
- @Override
- public boolean supportsAggregatesMax() {
- return delegate.supportsAggregatesMax();
- }
- @Override
- public boolean supportsAggregatesMin() {
- return delegate.supportsAggregatesMin();
- }
- @Override
- public boolean supportsAggregatesSum() {
- return delegate.supportsAggregatesSum();
- }
- @Override
- public boolean supportsAliasedTable() {
- return delegate.supportsAliasedTable();
- }
- @Override
- public boolean supportsBatchedUpdates() {
- return delegate.supportsBatchedUpdates();
- }
- @Override
- public boolean supportsBetweenCriteria() {
- return delegate.supportsBetweenCriteria();
- }
- @Override
- public boolean supportsBulkUpdate() {
- return delegate.supportsBulkUpdate();
- }
- @Override
- public boolean supportsCaseExpressions() {
- return delegate.supportsCaseExpressions();
- }
- @Override
- public boolean supportsCommonTableExpressions() {
- return delegate.supportsCommonTableExpressions();
- }
- @Override
- public boolean supportsCompareCriteriaEquals() {
- return delegate.supportsCompareCriteriaEquals();
- }
- @Override
- public boolean supportsCompareCriteriaOrdered() {
- return delegate.supportsCompareCriteriaOrdered();
- }
- @Override
- public boolean supportsCorrelatedSubqueries() {
- return delegate.supportsCorrelatedSubqueries();
- }
- @Override
- public boolean supportsExcept() {
- return delegate.supportsExcept();
- }
- @Override
- public boolean supportsExistsCriteria() {
- return delegate.supportsExistsCriteria();
- }
- @Override
- public boolean supportsFunctionsInGroupBy() {
- return delegate.supportsFunctionsInGroupBy();
- }
- @Override
- public boolean supportsGroupBy() {
- return delegate.supportsGroupBy();
- }
- @Override
- public boolean supportsHaving() {
- return delegate.supportsHaving();
- }
- @Override
- public boolean supportsInCriteria() {
- return delegate.supportsInCriteria();
- }
- @Override
- public boolean supportsInCriteriaSubquery() {
- return delegate.supportsInCriteriaSubquery();
- }
- @Override
- public boolean supportsInlineViews() {
- return delegate.supportsInlineViews();
- }
- @Override
- public boolean supportsInsertWithIterator() {
- return delegate.supportsInsertWithIterator();
- }
- @Override
- public boolean supportsInsertWithQueryExpression() {
- return delegate.supportsInsertWithQueryExpression();
- }
- @Override
- public boolean supportsIntersect() {
- return delegate.supportsIntersect();
- }
- @Override
- public boolean supportsIsNullCriteria() {
- return delegate.supportsIsNullCriteria();
- }
- @Override
- public boolean supportsLikeCriteria() {
- return delegate.supportsLikeCriteria();
- }
- @Override
- public boolean supportsLikeCriteriaEscapeCharacter() {
- return delegate.supportsLikeCriteriaEscapeCharacter();
- }
- @Override
- public boolean supportsNotCriteria() {
- return delegate.supportsNotCriteria();
- }
- @Override
- public boolean supportsOrCriteria() {
- return delegate.supportsOrCriteria();
- }
- @Override
- public boolean supportsOrderByNullOrdering() {
- return delegate.supportsOrderByNullOrdering();
- }
- @Override
- public boolean supportsOrderByUnrelated() {
- return delegate.supportsOrderByUnrelated();
- }
- @Override
- public boolean supportsQuantifiedCompareCriteriaAll() {
- return delegate.supportsQuantifiedCompareCriteriaAll();
- }
- @Override
- public boolean supportsQuantifiedCompareCriteriaSome() {
- return delegate.supportsQuantifiedCompareCriteriaSome();
- }
- @Override
- public boolean supportsRowLimit() {
- return delegate.supportsRowLimit();
- }
- @Override
- public boolean supportsRowOffset() {
- return delegate.supportsRowOffset();
- }
- @Override
- public boolean supportsScalarSubqueries() {
- return delegate.supportsScalarSubqueries();
- }
- @Override
- public boolean supportsSearchedCaseExpressions() {
- return delegate.supportsSearchedCaseExpressions();
- }
- @Override
- public boolean supportsSelectExpression() {
- return delegate.supportsSelectExpression();
- }
- @Override
- public boolean supportsSelfJoins() {
- return delegate.supportsSelfJoins();
- }
- @Override
- public boolean supportsSetQueryOrderBy() {
- return delegate.supportsSetQueryOrderBy();
- }
- @Override
- public boolean supportsUnions() {
- return delegate.supportsUnions();
- }
- @Override
- public String toString() {
- return delegate.toString();
- }
- @Override
- public boolean useAnsiJoin() {
- return delegate.useAnsiJoin();
- }
- @Override
- public boolean equals(Object obj) {
- return delegate.equals(obj);
- }
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java 2010-12-23 20:05:36 UTC (rev 2796)
+++ trunk/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java 2010-12-23 20:46:42 UTC (rev 2797)
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -52,6 +53,7 @@
import org.teiid.metadata.index.IndexMetadataFactory;
import org.teiid.query.metadata.TransformationMetadata.Resource;
import org.teiid.runtime.RuntimePlugin;
+import org.teiid.translator.DelegatingExecutionFactory;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.TranslatorException;
@@ -176,27 +178,41 @@
}
String name = model.getSourceTranslatorName(source);
- Translator translator = repo.getTranslatorMetaData(name);
- if (translator == null) {
- translator = this.translatorRepository.getTranslatorMetaData(name);
- }
- if (translator == null) {
- throw new DeploymentException(RuntimePlugin.Util.getString("translator_not_found", deployment.getName(), deployment.getVersion(), name)); //$NON-NLS-1$
- }
-
- ExecutionFactory<Object, Object> ef = map.get(translator);
- if ( ef == null) {
- ef = TranslatorUtil.buildExecutionFactory(translator);
- map.put(translator, ef);
- }
-
ConnectorManager cm = new ConnectorManager(name, model.getSourceConnectionJndiName(source));
+ ExecutionFactory<Object, Object> ef = getExecutionFactory(name, repo, deployment, map, new HashSet<String>());
cm.setExecutionFactory(ef);
cm.setModelName(model.getName());
cmr.addConnectorManager(source, cm);
}
}
}
+
+ private ExecutionFactory<Object, Object> getExecutionFactory(String name, TranslatorRepository repo, VDBMetaData deployment, IdentityHashMap<Translator, ExecutionFactory<Object, Object>> map, HashSet<String> building) throws DeploymentException {
+ if (!building.add(name)) {
+ throw new DeploymentException(RuntimePlugin.Util.getString("recursive_delegation", deployment.getName(), deployment.getVersion(), building)); //$NON-NLS-1$
+ }
+ Translator translator = repo.getTranslatorMetaData(name);
+ if (translator == null) {
+ translator = this.translatorRepository.getTranslatorMetaData(name);
+ }
+ if (translator == null) {
+ throw new DeploymentException(RuntimePlugin.Util.getString("translator_not_found", deployment.getName(), deployment.getVersion(), name)); //$NON-NLS-1$
+ }
+ ExecutionFactory<Object, Object> ef = map.get(translator);
+ if ( ef == null) {
+ ef = TranslatorUtil.buildExecutionFactory(translator);
+ if (ef instanceof DelegatingExecutionFactory) {
+ DelegatingExecutionFactory delegator = (DelegatingExecutionFactory)ef;
+ String delegateName = delegator.getDelegateName();
+ if (delegateName != null) {
+ ExecutionFactory<Object, Object> delegate = getExecutionFactory(delegateName, repo, deployment, map, building);
+ ((DelegatingExecutionFactory) ef).setDelegate(delegate);
+ }
+ }
+ map.put(translator, ef);
+ }
+ return ef;
+ }
private boolean validateSources(ConnectorManagerRepository cmr, VDBMetaData deployment) {
boolean valid = true;
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2010-12-23 20:05:36 UTC (rev 2796)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2010-12-23 20:46:42 UTC (rev 2797)
@@ -67,6 +67,7 @@
failed_matadata_load=Failed to load metadata for VDB {0}.{1}
vdb_not_found=VDB {0}.{1} not found deployed.
translator_not_found=For {0}.{1} VDB, Translator "{2}" not found.
+recursive_delegation=For {0}.{1} VDB, recursive delegation {2} found.
datasource_not_found=For {0}.{1} VDB, Data Source "{2}" not found.
vdb_activated={0}.{1} status has been changed to active
vdb_inactivated={0}.{1} status has been changed to inactive. Check the required translators and data sources!
14 years
teiid SVN: r2796 - in trunk: client/src/main/java/org/teiid/jdbc and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2010-12-23 15:05:36 -0500 (Thu, 23 Dec 2010)
New Revision: 2796
Added:
trunk/client/src/main/java/org/teiid/jdbc/TeiidConnection.java
Modified:
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
trunk/client/src/main/java/org/teiid/net/ServerConnection.java
trunk/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java
trunk/client/src/test/java/org/teiid/net/socket/TestSocketServerConnection.java
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
trunk/runtime/src/main/java/org/teiid/transport/LogonImpl.java
trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java
Log:
TEIID-192 adding reauthentication support
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-23 20:05:36 UTC (rev 2796)
@@ -38,6 +38,7 @@
<LI><B>Partition-wise Optimizations</B> - Views defined by partitioned unions (union alls where each branch has a projected literal or an IN predicate that makes its values mutually exclusive from the other branches) can
be used in aggregation or joins and the optimizer will take advantage of the partitioning information. For example, when a partitioned union is joined against another partitioned union, the optimizer will reorganize the join of unions into a union of joins.
<LI><B>Delegate Translator</B> - A new translator added that is capable of delegating all the calls to another configured translator.
+ <LI><B>JDBC Reauthentication</B> - Teiid connections (defined by the org.teiid.jdbc.TeiidConnection interface) now support the changeUser method to reauthenticate a given connection.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -58,6 +58,7 @@
import org.teiid.client.xa.XidImpl;
import org.teiid.core.util.SqlUtil;
import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
import org.teiid.net.ServerConnection;
import org.teiid.net.TeiidURL;
import org.teiid.net.socket.SocketServerConnection;
@@ -65,7 +66,7 @@
/**
* Teiid's Connection implementation.
*/
-public class ConnectionImpl extends WrapperImpl implements Connection {
+public class ConnectionImpl extends WrapperImpl implements TeiidConnection {
private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$
public static final int DEFAULT_ISOLATION = Connection.TRANSACTION_READ_COMMITTED;
@@ -109,9 +110,11 @@
// the last query debug log
private String debugLog;
// the last query annotations
- private Collection<Annotation> annotations;
+ private Collection<Annotation> annotations;
+ private Properties connectionProps;
- public ConnectionImpl(ServerConnection serverConn, Properties info, String url) {
+ public ConnectionImpl(ServerConnection serverConn, Properties info, String url) {
+ this.connectionProps = info;
this.serverConn = serverConn;
this.url = url;
this.dqp = serverConn.getService(DQP.class);
@@ -944,6 +947,46 @@
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ @Override
+ public void changeUser(String userName, String newPassword)
+ throws SQLException {
+ //TODO: recycleConnection();
+ Object oldName = null;
+ Object oldPassword = null;
+ if (userName != null) {
+ oldName = this.connectionProps.put(TeiidURL.CONNECTION.USER_NAME, userName);
+ } else {
+ oldName = this.connectionProps.remove(TeiidURL.CONNECTION.USER_NAME);
+ }
+ if (newPassword != null) {
+ oldPassword = this.connectionProps.put(TeiidURL.CONNECTION.PASSWORD, newPassword);
+ } else {
+ oldPassword = this.connectionProps.remove(TeiidURL.CONNECTION.PASSWORD);
+ }
+ boolean success = false;
+ try {
+ this.serverConn.authenticate();
+ success = true;
+ } catch (ConnectionException e) {
+ throw TeiidSQLException.create(e);
+ } catch (CommunicationException e) {
+ throw TeiidSQLException.create(e);
+ } finally {
+ if (!success) {
+ if (oldName != null) {
+ this.connectionProps.put(TeiidURL.CONNECTION.USER_NAME, oldName);
+ } else {
+ this.connectionProps.remove(TeiidURL.CONNECTION.USER_NAME);
+ }
+ if (oldPassword != null) {
+ this.connectionProps.put(TeiidURL.CONNECTION.PASSWORD, oldPassword);
+ } else {
+ this.connectionProps.remove(TeiidURL.CONNECTION.PASSWORD);
+ }
+ }
+ }
}
}
Added: trunk/client/src/main/java/org/teiid/jdbc/TeiidConnection.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidConnection.java (rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidConnection.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Optional methods supported by Teiid Connections.
+ */
+public interface TeiidConnection extends Connection {
+
+ /**
+ * Re-authenticate with the given username and password. If the re-authentication
+ * fails the connection will remain under the current user.
+ *
+ * @param userName
+ * the username to authenticate with
+ * @param newPassword
+ * the password to authenticate with
+ */
+ public void changeUser(String userName, String newPassword) throws SQLException;
+}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidConnection.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/client/src/main/java/org/teiid/net/ServerConnection.java
===================================================================
--- trunk/client/src/main/java/org/teiid/net/ServerConnection.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/client/src/main/java/org/teiid/net/ServerConnection.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -40,4 +40,6 @@
void cleanUp();
+ void authenticate() throws ConnectionException, CommunicationException;
+
}
\ No newline at end of file
Modified: trunk/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java
===================================================================
--- trunk/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -91,7 +91,7 @@
this.logon = this.getService(ILogon.class);
this.failOver = Boolean.valueOf(connProps.getProperty(TeiidURL.CONNECTION.AUTO_FAILOVER)).booleanValue();
this.failOver |= Boolean.valueOf(connProps.getProperty(TeiidURL.CONNECTION.ADMIN)).booleanValue();
- selectServerInstance();
+ selectServerInstance(false);
}
/**
@@ -100,7 +100,7 @@
* TODO: put more information on hostinfo as to process response time, last successful connect, etc.
* @throws ConnectionException
*/
- public synchronized SocketServerInstance selectServerInstance()
+ public synchronized SocketServerInstance selectServerInstance(boolean logoff)
throws CommunicationException, ConnectionException {
if (closed) {
throw new CommunicationException(JDBCPlugin.Util.getString("SocketServerConnection.closed")); //$NON-NLS-1$
@@ -124,9 +124,7 @@
ILogon newLogon = connect(hostInfo);
if (this.logonResult == null) {
try {
- this.logonResult = newLogon.logon(connProps);
- this.logonResults.put(this.serverInstance.getHostInfo(), this.logonResult);
- this.connectionFactory.connected(this.serverInstance, this.logonResult.getSessionToken());
+ logon(newLogon, logoff);
this.serverDiscovery.connectionSuccessful(hostInfo);
if (discoverHosts) {
List<HostInfo> updatedHosts = this.serverDiscovery.getKnownHosts(logonResult, this.serverInstance);
@@ -166,6 +164,23 @@
throw new CommunicationException(JDBCPlugin.Util.getString("SocketServerInstancePool.No_valid_host_available", hostCopy.toString())); //$NON-NLS-1$
}
+ private void logon(ILogon newLogon, boolean logoff) throws LogonException,
+ TeiidComponentException, CommunicationException {
+ LogonResult newResult = newLogon.logon(connProps);
+ SocketServerInstance instance = this.serverInstance;
+ if (logoff) {
+ if ("7.3".compareTo(this.serverInstance.getServerVersion()) <= 0) { //$NON-NLS-1$
+ //just remove the current instance - the server has already logged off the current user
+ LogonResult old = this.logonResults.remove(this.serverInstance.getHostInfo());
+ this.connectionFactory.disconnected(this.serverInstance, old.getSessionToken());
+ }
+ logoffAll();
+ }
+ this.logonResult = newResult;
+ this.logonResults.put(instance.getHostInfo(), this.logonResult);
+ this.connectionFactory.connected(instance, this.logonResult.getSessionToken());
+ }
+
private ILogon connect(HostInfo hostInfo) throws CommunicationException,
IOException {
hostInfo.setSsl(secure);
@@ -189,7 +204,7 @@
protected SocketServerInstance getInstance() throws CommunicationException {
if (failOver && System.currentTimeMillis() - lastPing > pingFailOverInterval) {
try {
- ResultsFuture<?> future = selectServerInstance().getService(ILogon.class).ping();
+ ResultsFuture<?> future = selectServerInstance(false).getService(ILogon.class).ping();
future.get();
} catch (SingleInstanceCommunicationException e) {
closeServerInstance();
@@ -204,7 +219,7 @@
}
lastPing = System.currentTimeMillis();
try {
- return selectServerInstance();
+ return selectServerInstance(false);
} catch (ConnectionException e) {
throw new CommunicationException(e);
}
@@ -234,6 +249,13 @@
logoff();
}
+ logoffAll();
+
+ this.closed = true;
+ this.serverDiscovery.shutdown();
+ }
+
+ private void logoffAll() {
for (Map.Entry<HostInfo, LogonResult> logonEntry : logonResults.entrySet()) {
try {
connect(logonEntry.getKey());
@@ -242,9 +264,6 @@
}
}
-
- this.closed = true;
- this.serverDiscovery.shutdown();
}
private void logoff() {
@@ -299,7 +318,7 @@
return false;
}
try {
- return selectServerInstance().getHostInfo().equals(((SocketServerConnection)otherService).selectServerInstance().getHostInfo());
+ return selectServerInstance(false).getHostInfo().equals(((SocketServerConnection)otherService).selectServerInstance(false).getHostInfo());
} catch (ConnectionException e) {
throw new CommunicationException(e);
}
@@ -316,4 +335,21 @@
public void setFailOverPingInterval(int pingFailOverInterval) {
this.pingFailOverInterval = pingFailOverInterval;
}
+
+ @Override
+ public void authenticate() throws ConnectionException,
+ CommunicationException {
+ if (this.serverInstance == null) {
+ selectServerInstance(true); //this will trigger a logon with the new credentials
+ } else {
+ ILogon logonInstance = this.serverInstance.getService(ILogon.class);
+ try {
+ this.logon(logonInstance, true);
+ } catch (LogonException e) {
+ throw new ConnectionException(e);
+ } catch (TeiidComponentException e) {
+ throw new CommunicationException(e);
+ }
+ }
+ }
}
\ No newline at end of file
Modified: trunk/client/src/test/java/org/teiid/net/socket/TestSocketServerConnection.java
===================================================================
--- trunk/client/src/test/java/org/teiid/net/socket/TestSocketServerConnection.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/client/src/test/java/org/teiid/net/socket/TestSocketServerConnection.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -54,8 +54,8 @@
/**
* <code>TestCase</case> for <code>SocketServerConnection</code>
* @see SocketServerConnection
- * @since Westport
*/
+@SuppressWarnings("nls")
public class TestSocketServerConnection {
private static final class FakeILogon implements ILogon {
@@ -83,7 +83,7 @@
Properties connectionProperties)
throws LogonException,
TeiidComponentException {
- return new LogonResult(new SessionToken(1, "fooUser"), "foo", 1, "fake"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return new LogonResult(new SessionToken(1, connectionProperties.getProperty(TeiidURL.CONNECTION.USER_NAME, "fooUser")), "foo", 1, "fake"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@Override
@@ -151,6 +151,15 @@
assertEquals(String.valueOf(1), connection.getLogonResult().getSessionID());
}
+ @Test public void testChangeUser() throws Exception {
+ Properties p = new Properties();
+ SocketServerConnection connection = createConnection(null, p);
+ assertEquals("fooUser", connection.getLogonResult().getUserName());
+ p.setProperty(TeiidURL.CONNECTION.USER_NAME, "newUser");
+ connection.authenticate();
+ assertEquals("newUser", connection.getLogonResult().getUserName());
+ }
+
/**
* Since the original instance is still open, this will be a transparent retry
*/
@@ -177,12 +186,15 @@
}
private SocketServerConnection createConnection(final Throwable throwException) throws CommunicationException, ConnectionException {
- return createConnection(throwException, new HostInfo("0.0.0.2", 1)); //$NON-NLS-1$
+ return createConnection(throwException, new Properties());
}
- private SocketServerConnection createConnection(final Throwable t, final HostInfo hostInfo)
+ private SocketServerConnection createConnection(final Throwable throwException, Properties p) throws CommunicationException, ConnectionException {
+ return createConnection(throwException, new HostInfo("0.0.0.2", 1), p); //$NON-NLS-1$
+ }
+
+ private SocketServerConnection createConnection(final Throwable t, final HostInfo hostInfo, Properties p)
throws CommunicationException, ConnectionException {
- Properties p = new Properties();
ServerDiscovery discovery = new UrlServerDiscovery(new TeiidURL(hostInfo.getHostName(), hostInfo.getPortNumber(), false));
SocketServerInstanceFactory instanceFactory = new SocketServerInstanceFactory() {
FakeILogon logon = new FakeILogon(t);
@@ -194,6 +206,7 @@
Mockito.stub(instance.getCryptor()).toReturn(new NullCryptor());
Mockito.stub(instance.getHostInfo()).toReturn(hostInfo);
Mockito.stub(instance.getService(ILogon.class)).toReturn(logon);
+ Mockito.stub(instance.getServerVersion()).toReturn("7.3");
if (t != null) {
try {
Mockito.doAnswer(new Answer<Void>() {
@@ -231,8 +244,8 @@
}
@Test public void testIsSameInstance() throws Exception {
- SocketServerConnection conn = createConnection(null, new HostInfo("0.0.0.0", 1)); //$NON-NLS-1$
- SocketServerConnection conn1 = createConnection(null, new HostInfo("0.0.0.1", 1)); //$NON-NLS-1$
+ SocketServerConnection conn = createConnection(null, new HostInfo("0.0.0.0", 1), new Properties()); //$NON-NLS-1$
+ SocketServerConnection conn1 = createConnection(null, new HostInfo("0.0.0.1", 1), new Properties()); //$NON-NLS-1$
assertFalse(conn.isSameInstance(conn1));
assertTrue(conn.isSameInstance(conn));
Modified: trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
===================================================================
--- trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2010-12-23 20:05:36 UTC (rev 2796)
@@ -536,5 +536,10 @@
<para>Your customized server discovery class will then need to be referenced by the discoveryStategy connection/DataSource property by its full class name.</para>
</section>
</section>
-
+ <section>
+ <title>Reauthentication</title>
+ <para>Teiid connections (defined by the <code>org.teiid.jdbc.TeiidConnection</code> interface) support the changeUser method to reauthenticate a given connection.
+ If the reauthentication is successful the current connection my be used with the given identity.
+ Existing statements/result sets are still available for use under the old identity. See the JBossAS issue <ulink url="https://issues.jboss.org/browse/JBAS-1429">JBAS-1429</ulink> for more on using reauthentication support with JCA.</para>
+ </section>
</chapter>
\ No newline at end of file
Modified: trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -62,7 +62,7 @@
this.connectionProperties = connectionProperties;
this.csr = getClientServiceRegistry();
workContext.setSecurityHelper(csr.getSecurityHelper());
- authenticate(connectionProperties);
+ authenticate();
passthrough = Boolean.valueOf(connectionProperties.getProperty(TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION, "false")); //$NON-NLS-1$
}
@@ -75,9 +75,9 @@
}
}
- public synchronized void authenticate(Properties connProps) throws ConnectionException, CommunicationException {
+ public synchronized void authenticate() throws ConnectionException, CommunicationException {
try {
- this.result = this.getService(ILogon.class).logon(connProps);
+ this.result = this.getService(ILogon.class).logon(this.connectionProperties);
} catch (LogonException e) {
// Propagate the original message as it contains the message we want
// to give to the user
@@ -101,8 +101,7 @@
if (passthrough && !arg1.getDeclaringClass().equals(ILogon.class)) {
// check to make sure the current security context same as logged one
if (!csr.getSecurityHelper().sameSubject(workContext.getSession().getSecurityDomain(), workContext.getSession().getSecurityContext(), workContext.getSubject())) {
- logoff();
- authenticate(connectionProperties);
+ authenticate();
}
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/LogonImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/LogonImpl.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/runtime/src/main/java/org/teiid/transport/LogonImpl.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -59,7 +59,8 @@
public LogonResult logon(Properties connProps) throws LogonException,
ComponentNotFoundException {
-
+ DQPWorkContext workContext = DQPWorkContext.getWorkContext();
+ SessionToken oldToken = workContext.getSessionToken();
String applicationName = connProps.getProperty(TeiidURL.CONNECTION.APP_NAME);
// user may be null if using trustedToken to log on
String user = connProps.getProperty(TeiidURL.CONNECTION.USER_NAME, CoreConstants.DEFAULT_ANON_USERNAME);
@@ -77,6 +78,12 @@
if (DQPWorkContext.getWorkContext().getClientAddress() == null) {
sessionInfo.setEmbedded(true);
}
+ if (oldToken != null) {
+ try {
+ this.service.closeSession(oldToken.getSessionID());
+ } catch (InvalidSessionException e) {
+ }
+ }
return new LogonResult(sessionInfo.getSessionToken(), sessionInfo.getVDBName(), sessionInfo.getVDBVersion(), clusterName);
} catch (LoginException e) {
throw new LogonException(e.getMessage());
Modified: trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java 2010-12-23 18:26:05 UTC (rev 2795)
+++ trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java 2010-12-23 20:05:36 UTC (rev 2796)
@@ -140,7 +140,7 @@
SSLConfiguration config = new SSLConfiguration();
config.setMode(SSLConfiguration.DISABLED);
SocketServerConnection conn = helpEstablishConnection(false, config, new Properties());
- assertTrue(conn.selectServerInstance().getCryptor() instanceof NullCryptor);
+ assertTrue(conn.selectServerInstance(false).getCryptor() instanceof NullCryptor);
conn.close();
}
14 years
teiid SVN: r2795 - in trunk: build/kits/jboss-container and 2 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2010-12-23 13:26:05 -0500 (Thu, 23 Dec 2010)
New Revision: 2795
Added:
trunk/connectors/translator-delegate/target/
Modified:
trunk/build/assembly/jboss-container/dist.xml
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
Log:
TEIID-1330: Adding the delegate translator
Modified: trunk/build/assembly/jboss-container/dist.xml
===================================================================
--- trunk/build/assembly/jboss-container/dist.xml 2010-12-23 18:22:52 UTC (rev 2794)
+++ trunk/build/assembly/jboss-container/dist.xml 2010-12-23 18:26:05 UTC (rev 2795)
@@ -184,6 +184,7 @@
<include>org.jboss.teiid.connectors:translator-ldap</include>
<include>org.jboss.teiid.connectors:translator-salesforce</include>
<include>org.jboss.teiid.connectors:translator-ws</include>
+ <include>org.jboss.teiid.connectors:translator-delegate</include>
</includes>
<binaries>
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-23 18:22:52 UTC (rev 2794)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-23 18:26:05 UTC (rev 2795)
@@ -37,6 +37,7 @@
<LI><B>Predicate Optimization</B> - expanded optimizations for detecting always false conditions when using IS NULL, IN, or comparison predicates with literal values.
<LI><B>Partition-wise Optimizations</B> - Views defined by partitioned unions (union alls where each branch has a projected literal or an IN predicate that makes its values mutually exclusive from the other branches) can
be used in aggregation or joins and the optimizer will take advantage of the partitioning information. For example, when a partitioned union is joined against another partitioned union, the optimizer will reorganize the join of unions into a union of joins.
+ <LI><B>Delegate Translator</B> - A new translator added that is capable of delegating all the calls to another configured translator.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2010-12-23 18:22:52 UTC (rev 2794)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2010-12-23 18:26:05 UTC (rev 2795)
@@ -1009,6 +1009,40 @@
</section>
</section>
</section>
+ <section>
+ <title>Delegate Translator</title>
+ <para>
+ The Delegate translator, known by the type name <emphasis>delegate</emphasis>,
+ provides way to delegate all the translator calls to yet another translator whoose name is supplied. This does not provide
+ any functionality on its own, other than delegation. This translator can be used to intercept the calls to the user
+ supplied translator and modify them as they see fit. Another advantage of this translator is, user is not required to
+ package their translator as precribed in JAR file as shown in the developer's guide, all user need to do
+ is to make sure the supplied class is availble in classpath that is used by 'delegate' translator.
+ </para>
+
+ <table>
+ <title>Execution Properties</title>
+ <tgroup cols="3">
+ <colspec colwidth="3*" />
+ <colspec colwidth="6*" />
+ <colspec colwidth="2*" />
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ <entry>Default</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>delegateClassName</entry>
+ <entry>User defined ExcutionFactory class name, to be delegated to</entry>
+ <entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
</section>
<section id="dynamic_vdbs">
14 years
teiid SVN: r2794 - in trunk/connectors: translator-delegate and 15 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2010-12-23 13:22:52 -0500 (Thu, 23 Dec 2010)
New Revision: 2794
Added:
trunk/connectors/translator-delegate/
trunk/connectors/translator-delegate/pom.xml
trunk/connectors/translator-delegate/src/
trunk/connectors/translator-delegate/src/main/
trunk/connectors/translator-delegate/src/main/java/
trunk/connectors/translator-delegate/src/main/java/org/
trunk/connectors/translator-delegate/src/main/java/org/teiid/
trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/
trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/
trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java
trunk/connectors/translator-delegate/src/main/resources/
trunk/connectors/translator-delegate/src/main/resources/META-INF/
trunk/connectors/translator-delegate/src/main/resources/META-INF/jboss-beans.xml
trunk/connectors/translator-delegate/src/test/
trunk/connectors/translator-delegate/src/test/java/
trunk/connectors/translator-delegate/src/test/java/org/
trunk/connectors/translator-delegate/src/test/java/org/teiid/
trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/
trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/
trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/Delegatee.java
trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/TestDelegateExecutionFactory.java
Modified:
trunk/connectors/pom.xml
Log:
TEIID-1330: adding delegating translator
Modified: trunk/connectors/pom.xml
===================================================================
--- trunk/connectors/pom.xml 2010-12-23 17:46:42 UTC (rev 2793)
+++ trunk/connectors/pom.xml 2010-12-23 18:22:52 UTC (rev 2794)
@@ -80,6 +80,7 @@
<module>translator-loopback</module>
<module>translator-file</module>
<module>translator-salesforce</module>
+ <module>translator-delegate</module>
<module>connector-file</module>
<module>connector-salesforce</module>
Property changes on: trunk/connectors/translator-delegate
___________________________________________________________________
Name: svn:ignore
+ .project
.classpath
.settings
Added: trunk/connectors/translator-delegate/pom.xml
===================================================================
--- trunk/connectors/translator-delegate/pom.xml (rev 0)
+++ trunk/connectors/translator-delegate/pom.xml 2010-12-23 18:22:52 UTC (rev 2794)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>connectors</artifactId>
+ <groupId>org.jboss.teiid</groupId>
+ <version>7.3.0.Alpha2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>translator-delegate</artifactId>
+ <groupId>org.jboss.teiid.connectors</groupId>
+ <name>Delegate Translator</name>
+ <description>Delegate Translator</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-common-core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.resource</groupId>
+ <artifactId>connector-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <outputDirectory>target/classes</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.xml</include>
+ <include>**/*.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>false</filtering>
+ <excludes>
+ <exclude>**/*.xml</exclude>
+ <exclude>**/*.properties</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+</project>
Added: trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java
===================================================================
--- trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java (rev 0)
+++ trunk/connectors/translator-delegate/src/main/java/org/teiid/translator/delegate/DelegateExecutionFactory.java 2010-12-23 18:22:52 UTC (rev 2794)
@@ -0,0 +1,399 @@
+/*
+ * 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.delegate;
+
+import java.util.List;
+
+import org.teiid.language.Call;
+import org.teiid.language.Command;
+import org.teiid.language.LanguageFactory;
+import org.teiid.language.QueryExpression;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.Execution;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ExecutionFactory;
+import org.teiid.translator.ProcedureExecution;
+import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.Translator;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TranslatorProperty;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.UpdateExecution;
+
+/**
+ * Delegate translator. User can define a {@link ExecutionFactory} of their own and have this translator
+ * delegate all the calls to that class. This will help user to avoid packing their translator in the required
+ * jar packaging and lets the user intercept the calls for their needs. Please note that your 'vdb.xml' file contains
+ * the following xml fragment to configure this translator to delegate calls to custom translator.
+ * <pre>
+ * {@code
+ <translator type="delegate" name="my-translator" description="custom translator">
+ <property value="delegateClassName" name="name of class that implements custom execution factory"/>
+ </translator>
+ }
+ * </pre>
+ *
+ */
+@Translator(name="delegate", description="A translator that acts as delegator to the another translator")
+public class DelegateExecutionFactory<F, C> extends ExecutionFactory {
+
+ private String delegateClassName;
+ private ExecutionFactory delegate;
+
+ @TranslatorProperty(display="Delegatee class name", required = true)
+ public String getDelegateClassName() {
+ return this.delegateClassName;
+ }
+
+ public void setDelegateClassName(String delegateName) {
+ this.delegateClassName = delegateName;
+ }
+
+ /**
+ * For testing only
+ */
+ ExecutionFactory getDelegatee() {
+ return this.delegate;
+ }
+
+ @Override
+ public void start() throws TranslatorException {
+ this.delegate = getInstance(ExecutionFactory.class, this.delegateClassName,null, null);
+ this.delegate.start();
+ }
+ @Override
+ public boolean areLobsUsableAfterClose() {
+ return delegate.areLobsUsableAfterClose();
+ }
+ @Override
+ public void closeConnection(Object connection, Object factory) {
+ delegate.closeConnection(connection, factory);
+ }
+ @Override
+ public Execution createExecution(Command command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ Object connection) throws TranslatorException {
+ return delegate.createExecution(command, executionContext, metadata,
+ connection);
+ }
+ @Override
+ public ProcedureExecution createProcedureExecution(Call command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ Object connection) throws TranslatorException {
+ return delegate.createProcedureExecution(command, executionContext,
+ metadata, connection);
+ }
+ @Override
+ public ResultSetExecution createResultSetExecution(QueryExpression command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ Object connection) throws TranslatorException {
+ return delegate.createResultSetExecution(command, executionContext,
+ metadata, connection);
+ }
+ @Override
+ public UpdateExecution createUpdateExecution(Command command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ Object connection) throws TranslatorException {
+ return delegate.createUpdateExecution(command, executionContext,
+ metadata, connection);
+ }
+ @Override
+ public Object getConnection(Object factory) throws TranslatorException {
+ return delegate.getConnection(factory);
+ }
+ @Override
+ public NullOrder getDefaultNullOrder() {
+ return delegate.getDefaultNullOrder();
+ }
+ @Override
+ public LanguageFactory getLanguageFactory() {
+ return delegate.getLanguageFactory();
+ }
+ @Override
+ public int getMaxFromGroups() {
+ return delegate.getMaxFromGroups();
+ }
+ @Override
+ public int getMaxInCriteriaSize() {
+ return delegate.getMaxInCriteriaSize();
+ }
+ @Override
+ public void getMetadata(MetadataFactory metadataFactory, Object conn)
+ throws TranslatorException {
+ delegate.getMetadata(metadataFactory, conn);
+ }
+ @Override
+ public List getPushDownFunctions() {
+ return delegate.getPushDownFunctions();
+ }
+ @Override
+ public List getSupportedFunctions() {
+ return delegate.getSupportedFunctions();
+ }
+ @Override
+ public TypeFacility getTypeFacility() {
+ return delegate.getTypeFacility();
+ }
+ @Override
+ public boolean isImmutable() {
+ return delegate.isImmutable();
+ }
+ @Override
+ public boolean isSourceRequired() {
+ return delegate.isSourceRequired();
+ }
+ @Override
+ public void setImmutable(boolean arg0) {
+ delegate.setImmutable(arg0);
+ }
+ @Override
+ public void setRequiresCriteria(boolean requiresCriteria) {
+ delegate.setRequiresCriteria(requiresCriteria);
+ }
+ @Override
+ public void setSourceRequired(boolean value) {
+ delegate.setSourceRequired(value);
+ }
+ @Override
+ public void setSupportedJoinCriteria(
+ SupportedJoinCriteria supportedJoinCriteria) {
+ delegate.setSupportedJoinCriteria(supportedJoinCriteria);
+ }
+ @Override
+ public void setSupportsFullOuterJoins(boolean supportsFullOuterJoins) {
+ delegate.setSupportsFullOuterJoins(supportsFullOuterJoins);
+ }
+ @Override
+ public void setSupportsInnerJoins(boolean supportsInnerJoins) {
+ delegate.setSupportsInnerJoins(supportsInnerJoins);
+ }
+ @Override
+ public void setSupportsOrderBy(boolean supportsOrderBy) {
+ delegate.setSupportsOrderBy(supportsOrderBy);
+ }
+ @Override
+ public void setSupportsOuterJoins(boolean supportsOuterJoins) {
+ delegate.setSupportsOuterJoins(supportsOuterJoins);
+ }
+ @Override
+ public void setSupportsSelectDistinct(boolean supportsSelectDistinct) {
+ delegate.setSupportsSelectDistinct(supportsSelectDistinct);
+ }
+ @Override
+ public boolean supportsAggregatesAvg() {
+ return delegate.supportsAggregatesAvg();
+ }
+ @Override
+ public boolean supportsAggregatesCount() {
+ return delegate.supportsAggregatesCount();
+ }
+ @Override
+ public boolean supportsAggregatesCountStar() {
+ return delegate.supportsAggregatesCountStar();
+ }
+ @Override
+ public boolean supportsAggregatesDistinct() {
+ return delegate.supportsAggregatesDistinct();
+ }
+ @Override
+ public boolean supportsAggregatesEnhancedNumeric() {
+ return delegate.supportsAggregatesEnhancedNumeric();
+ }
+ @Override
+ public boolean supportsAggregatesMax() {
+ return delegate.supportsAggregatesMax();
+ }
+ @Override
+ public boolean supportsAggregatesMin() {
+ return delegate.supportsAggregatesMin();
+ }
+ @Override
+ public boolean supportsAggregatesSum() {
+ return delegate.supportsAggregatesSum();
+ }
+ @Override
+ public boolean supportsAliasedTable() {
+ return delegate.supportsAliasedTable();
+ }
+ @Override
+ public boolean supportsBatchedUpdates() {
+ return delegate.supportsBatchedUpdates();
+ }
+ @Override
+ public boolean supportsBetweenCriteria() {
+ return delegate.supportsBetweenCriteria();
+ }
+ @Override
+ public boolean supportsBulkUpdate() {
+ return delegate.supportsBulkUpdate();
+ }
+ @Override
+ public boolean supportsCaseExpressions() {
+ return delegate.supportsCaseExpressions();
+ }
+ @Override
+ public boolean supportsCommonTableExpressions() {
+ return delegate.supportsCommonTableExpressions();
+ }
+ @Override
+ public boolean supportsCompareCriteriaEquals() {
+ return delegate.supportsCompareCriteriaEquals();
+ }
+ @Override
+ public boolean supportsCompareCriteriaOrdered() {
+ return delegate.supportsCompareCriteriaOrdered();
+ }
+ @Override
+ public boolean supportsCorrelatedSubqueries() {
+ return delegate.supportsCorrelatedSubqueries();
+ }
+ @Override
+ public boolean supportsExcept() {
+ return delegate.supportsExcept();
+ }
+ @Override
+ public boolean supportsExistsCriteria() {
+ return delegate.supportsExistsCriteria();
+ }
+ @Override
+ public boolean supportsFunctionsInGroupBy() {
+ return delegate.supportsFunctionsInGroupBy();
+ }
+ @Override
+ public boolean supportsGroupBy() {
+ return delegate.supportsGroupBy();
+ }
+ @Override
+ public boolean supportsHaving() {
+ return delegate.supportsHaving();
+ }
+ @Override
+ public boolean supportsInCriteria() {
+ return delegate.supportsInCriteria();
+ }
+ @Override
+ public boolean supportsInCriteriaSubquery() {
+ return delegate.supportsInCriteriaSubquery();
+ }
+ @Override
+ public boolean supportsInlineViews() {
+ return delegate.supportsInlineViews();
+ }
+ @Override
+ public boolean supportsInsertWithIterator() {
+ return delegate.supportsInsertWithIterator();
+ }
+ @Override
+ public boolean supportsInsertWithQueryExpression() {
+ return delegate.supportsInsertWithQueryExpression();
+ }
+ @Override
+ public boolean supportsIntersect() {
+ return delegate.supportsIntersect();
+ }
+ @Override
+ public boolean supportsIsNullCriteria() {
+ return delegate.supportsIsNullCriteria();
+ }
+ @Override
+ public boolean supportsLikeCriteria() {
+ return delegate.supportsLikeCriteria();
+ }
+ @Override
+ public boolean supportsLikeCriteriaEscapeCharacter() {
+ return delegate.supportsLikeCriteriaEscapeCharacter();
+ }
+ @Override
+ public boolean supportsNotCriteria() {
+ return delegate.supportsNotCriteria();
+ }
+ @Override
+ public boolean supportsOrCriteria() {
+ return delegate.supportsOrCriteria();
+ }
+ @Override
+ public boolean supportsOrderByNullOrdering() {
+ return delegate.supportsOrderByNullOrdering();
+ }
+ @Override
+ public boolean supportsOrderByUnrelated() {
+ return delegate.supportsOrderByUnrelated();
+ }
+ @Override
+ public boolean supportsQuantifiedCompareCriteriaAll() {
+ return delegate.supportsQuantifiedCompareCriteriaAll();
+ }
+ @Override
+ public boolean supportsQuantifiedCompareCriteriaSome() {
+ return delegate.supportsQuantifiedCompareCriteriaSome();
+ }
+ @Override
+ public boolean supportsRowLimit() {
+ return delegate.supportsRowLimit();
+ }
+ @Override
+ public boolean supportsRowOffset() {
+ return delegate.supportsRowOffset();
+ }
+ @Override
+ public boolean supportsScalarSubqueries() {
+ return delegate.supportsScalarSubqueries();
+ }
+ @Override
+ public boolean supportsSearchedCaseExpressions() {
+ return delegate.supportsSearchedCaseExpressions();
+ }
+ @Override
+ public boolean supportsSelectExpression() {
+ return delegate.supportsSelectExpression();
+ }
+ @Override
+ public boolean supportsSelfJoins() {
+ return delegate.supportsSelfJoins();
+ }
+ @Override
+ public boolean supportsSetQueryOrderBy() {
+ return delegate.supportsSetQueryOrderBy();
+ }
+ @Override
+ public boolean supportsUnions() {
+ return delegate.supportsUnions();
+ }
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ @Override
+ public boolean useAnsiJoin() {
+ return delegate.useAnsiJoin();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return delegate.equals(obj);
+ }
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+}
Added: trunk/connectors/translator-delegate/src/main/resources/META-INF/jboss-beans.xml
===================================================================
--- trunk/connectors/translator-delegate/src/main/resources/META-INF/jboss-beans.xml (rev 0)
+++ trunk/connectors/translator-delegate/src/main/resources/META-INF/jboss-beans.xml 2010-12-23 18:22:52 UTC (rev 2794)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+
+ <bean name="translator-delegate-template" class="org.teiid.templates.TranslatorDeploymentTemplate">
+ <property name="info"><inject bean="translator-delegate"/></property>
+ <property name="managedObjectFactory"><inject bean="ManagedObjectFactory"/></property>
+ </bean>
+
+ <bean name="translator-delegate" class="org.teiid.templates.TranslatorTemplateInfo">
+ <constructor factoryMethod="createTemplateInfo">
+ <factory bean="TranslatorDeploymentTemplateInfoFactory"/>
+ <parameter class="java.lang.Class">org.teiid.templates.TranslatorTemplateInfo</parameter>
+ <parameter class="java.lang.Class">org.teiid.translator.delegate.DelegateExecutionFactory</parameter>
+ <parameter class="java.lang.String">translator-delegate</parameter>
+ <parameter class="java.lang.String">Delegate Translator</parameter>
+ </constructor>
+ </bean>
+
+</deployment>
Added: trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/Delegatee.java
===================================================================
--- trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/Delegatee.java (rev 0)
+++ trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/Delegatee.java 2010-12-23 18:22:52 UTC (rev 2794)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.delegate;
+
+import java.sql.Connection;
+
+import javax.sql.DataSource;
+
+import org.teiid.language.Command;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.Execution;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ExecutionFactory;
+import org.teiid.translator.TranslatorException;
+
+public class Delegatee extends ExecutionFactory<DataSource, Connection>{
+ public boolean connectionInvoked = false;
+ public boolean executionInvoked = false;
+
+ @Override
+ public Connection getConnection(DataSource factory)
+ throws TranslatorException {
+ connectionInvoked = true;
+ return null;
+ }
+
+ @Override
+ public Execution createExecution(Command command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ Connection connection) throws TranslatorException {
+ executionInvoked = true;
+ return null;
+ }
+
+
+}
\ No newline at end of file
Added: trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/TestDelegateExecutionFactory.java
===================================================================
--- trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/TestDelegateExecutionFactory.java (rev 0)
+++ trunk/connectors/translator-delegate/src/test/java/org/teiid/translator/delegate/TestDelegateExecutionFactory.java 2010-12-23 18:22:52 UTC (rev 2794)
@@ -0,0 +1,48 @@
+/*
+ * 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.delegate;
+
+import static org.junit.Assert.assertTrue;
+
+import javax.sql.DataSource;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+@SuppressWarnings("nls")
+public class TestDelegateExecutionFactory {
+
+ @Test
+ public void testDeleteTranslator() throws Exception {
+
+ DelegateExecutionFactory def = new DelegateExecutionFactory();
+ def.setDelegateClassName("org.teiid.translator.delegate.Delegatee");
+ def.start();
+
+ def.getConnection(Mockito.mock(DataSource.class));
+ Delegatee delegatee = (Delegatee)def.getDelegatee();
+ assertTrue(delegatee.connectionInvoked);
+
+ def.createExecution(null, null, null, null);
+ assertTrue(delegatee.executionInvoked);
+ }
+}
\ No newline at end of file
14 years
teiid SVN: r2793 - in branches/7.1.x/client/src: main/java/org/teiid/netty/handler/codec/serialization and 2 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2010-12-23 12:46:42 -0500 (Thu, 23 Dec 2010)
New Revision: 2793
Modified:
branches/7.1.x/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
branches/7.1.x/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java
branches/7.1.x/client/src/test/java/org/teiid/jdbc/TestPreparedStatement.java
branches/7.1.x/client/src/test/java/org/teiid/netty/handler/codec/serialization/TestObjectDecoderInputStream.java
Log:
TEIID-1407: Fixing the NotSeializable exception in the case of inserting lobs
Modified: branches/7.1.x/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
===================================================================
--- branches/7.1.x/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java 2010-12-23 01:51:14 UTC (rev 2792)
+++ branches/7.1.x/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java 2010-12-23 17:46:42 UTC (rev 2793)
@@ -300,6 +300,10 @@
* @throws SQLException if parameter type/datatype do not match
*/
public void setBlob (int parameterIndex, Blob x) throws SQLException {
+ if (x == null) {
+ this.setObject(parameterIndex, null);
+ return;
+ }
setObject(parameterIndex, x);
}
@@ -345,6 +349,10 @@
* @throws SQLException if parameter type/datatype do not match.
*/
public void setClob (int parameterIndex, Clob x) throws SQLException {
+ if (x == null) {
+ this.setObject(parameterIndex, null);
+ return;
+ }
setObject(parameterIndex, x);
}
@@ -697,6 +705,10 @@
public void setBlob(int parameterIndex, final InputStream inputStream)
throws SQLException {
+ if (inputStream == null) {
+ this.setObject(parameterIndex, null);
+ return;
+ }
this.setObject(parameterIndex, new BlobImpl(new InputStreamFactory() {
@Override
public InputStream getInputStream() throws IOException {
@@ -720,6 +732,10 @@
}
public void setClob(int parameterIndex, final Reader reader) throws SQLException {
+ if (reader == null) {
+ this.setObject(parameterIndex, null);
+ return;
+ }
this.setObject(parameterIndex, new ClobImpl(new InputStreamFactory() {
@Override
Modified: branches/7.1.x/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java
===================================================================
--- branches/7.1.x/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java 2010-12-23 01:51:14 UTC (rev 2792)
+++ branches/7.1.x/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java 2010-12-23 17:46:42 UTC (rev 2793)
@@ -65,6 +65,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidException;
import org.teiid.core.TeiidRuntimeException;
+import org.teiid.core.types.BaseLob;
import org.teiid.core.types.BlobImpl;
import org.teiid.core.types.BlobType;
import org.teiid.core.types.ClobImpl;
@@ -182,40 +183,63 @@
@Override
protected Object replaceObject(Object obj) throws IOException {
- if (obj instanceof Serializable) {
+ if (obj instanceof BaseLob) {
+ try {
+ if (obj instanceof SQLXMLImpl) {
+ streams.add(((SQLXMLImpl)obj).getBinaryStream());
+ StreamFactoryReference sfr = new SQLXMLImpl();
+ references.add(sfr);
+ return sfr;
+ } else if (obj instanceof ClobImpl) {
+ streams.add(new ReaderInputStream(((ClobImpl)obj).getCharacterStream(), Charset.forName(Streamable.ENCODING)));
+ StreamFactoryReference sfr = new ClobImpl();
+ references.add(sfr);
+ return sfr;
+ } else if (obj instanceof BlobImpl) {
+ streams.add(((Blob)obj).getBinaryStream());
+ StreamFactoryReference sfr = new BlobImpl();
+ references.add(sfr);
+ return sfr;
+ }
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (obj instanceof Serializable) {
return obj;
}
- try {
- if (obj instanceof Reader) {
- streams.add(new ReaderInputStream((Reader)obj, Charset.forName(Streamable.ENCODING)));
- StreamFactoryReference sfr = new SerializableReader();
- references.add(sfr);
- return sfr;
- } else if (obj instanceof InputStream) {
- streams.add((InputStream)obj);
- StreamFactoryReference sfr = new SerializableInputStream();
- references.add(sfr);
- return sfr;
- } else if (obj instanceof SQLXML) {
- streams.add(((SQLXML)obj).getBinaryStream());
- StreamFactoryReference sfr = new SQLXMLImpl();
- references.add(sfr);
- return sfr;
- } else if (obj instanceof Clob) {
- //TODO: see if this is a ClobImpl and grab the underlying stream
- streams.add(new ReaderInputStream(((Clob)obj).getCharacterStream(), Charset.forName(Streamable.ENCODING)));
- StreamFactoryReference sfr = new ClobImpl();
- references.add(sfr);
- return sfr;
- } else if (obj instanceof Blob) {
- streams.add(((Blob)obj).getBinaryStream());
- StreamFactoryReference sfr = new BlobImpl();
- references.add(sfr);
- return sfr;
- }
- } catch (SQLException e) {
- throw new IOException(e);
- }
+ else {
+ try {
+ if (obj instanceof Reader) {
+ streams.add(new ReaderInputStream((Reader)obj, Charset.forName(Streamable.ENCODING)));
+ StreamFactoryReference sfr = new SerializableReader();
+ references.add(sfr);
+ return sfr;
+ } else if (obj instanceof InputStream) {
+ streams.add((InputStream)obj);
+ StreamFactoryReference sfr = new SerializableInputStream();
+ references.add(sfr);
+ return sfr;
+ } else if (obj instanceof SQLXML) {
+ streams.add(((SQLXML)obj).getBinaryStream());
+ StreamFactoryReference sfr = new SQLXMLImpl();
+ references.add(sfr);
+ return sfr;
+ } else if (obj instanceof Clob) {
+ streams.add(new ReaderInputStream(((Clob)obj).getCharacterStream(), Charset.forName(Streamable.ENCODING)));
+ StreamFactoryReference sfr = new ClobImpl();
+ references.add(sfr);
+ return sfr;
+ } else if (obj instanceof Blob) {
+ streams.add(((Blob)obj).getBinaryStream());
+ StreamFactoryReference sfr = new BlobImpl();
+ references.add(sfr);
+ return sfr;
+ }
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
return super.replaceObject(obj);
}
Modified: branches/7.1.x/client/src/test/java/org/teiid/jdbc/TestPreparedStatement.java
===================================================================
--- branches/7.1.x/client/src/test/java/org/teiid/jdbc/TestPreparedStatement.java 2010-12-23 01:51:14 UTC (rev 2792)
+++ branches/7.1.x/client/src/test/java/org/teiid/jdbc/TestPreparedStatement.java 2010-12-23 17:46:42 UTC (rev 2793)
@@ -24,6 +24,7 @@
import static org.junit.Assert.*;
+import java.sql.Blob;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -210,6 +211,11 @@
assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
}
+ @Test public void testSetBlob() throws Exception {
+ PreparedStatementImpl stmt = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+ stmt.setBlob(1, (Blob)null);
+ }
+
/**
* Test the <code>addBatch()</code> method of <code>MMPreparedStatement</code>
* using a batch with an empty parameter value list. The test will verify
Modified: branches/7.1.x/client/src/test/java/org/teiid/netty/handler/codec/serialization/TestObjectDecoderInputStream.java
===================================================================
--- branches/7.1.x/client/src/test/java/org/teiid/netty/handler/codec/serialization/TestObjectDecoderInputStream.java 2010-12-23 01:51:14 UTC (rev 2792)
+++ branches/7.1.x/client/src/test/java/org/teiid/netty/handler/codec/serialization/TestObjectDecoderInputStream.java 2010-12-23 17:46:42 UTC (rev 2793)
@@ -28,11 +28,17 @@
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.StringReader;
import java.net.SocketTimeoutException;
+import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
+import org.teiid.core.types.ClobImpl;
+import org.teiid.core.types.InputStreamFactory;
+import org.teiid.core.types.Streamable;
+import org.teiid.core.util.ReaderInputStream;
import static org.junit.Assert.*;
@@ -76,4 +82,23 @@
assertEquals(testValue, ObjectDecoderInputStream.getIntFromBytes(baos.toByteArray()));
}
+
+ @Test public void testReplaceObject() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectEncoderOutputStream out = new ObjectEncoderOutputStream(new DataOutputStream(baos), 512);
+
+ ClobImpl clob = new ClobImpl(new InputStreamFactory() {
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ReaderInputStream(new StringReader("Clob contents"), Charset.forName(Streamable.ENCODING)); //$NON-NLS-1$
+ }
+
+ }, -1);
+
+ out.writeObject(clob);
+
+ ObjectDecoderInputStream in = new ObjectDecoderInputStream(new DataInputStream(new ByteArrayInputStream(baos.toByteArray())), Thread.currentThread().getContextClassLoader(), 1024);
+ Object result = in.readObject();
+ assertTrue(result instanceof ClobImpl);
+ }
}
14 years
teiid SVN: r2792 - in trunk/engine/src: main/java/org/teiid/query/optimizer/relational/plantree and 2 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2010-12-22 20:51:14 -0500 (Wed, 22 Dec 2010)
New Revision: 2792
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
Log:
TEIID-1376 ensuring that merging will not invalidate the partition info
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java 2010-12-22 16:13:59 UTC (rev 2791)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java 2010-12-23 01:51:14 UTC (rev 2792)
@@ -23,6 +23,7 @@
package org.teiid.query.optimizer.relational;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -35,6 +36,7 @@
import java.util.TreeSet;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.query.sql.lang.CompareCriteria;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.Query;
import org.teiid.query.sql.lang.QueryCommand;
@@ -114,8 +116,20 @@
private static Map<ElementSymbol, Set<Constant>> extractPartitionInfo(Query query, List<ElementSymbol> projectedSymbols) {
List<SingleElementSymbol> projected = query.getSelect().getProjectedSymbols();
List<Criteria> crits = Criteria.separateCriteriaByAnd(query.getCriteria());
- Map<Expression, TreeSet<Constant>> inMap = new HashMap<Expression, TreeSet<Constant>>();
+ Map<Expression, Set<Constant>> inMap = new HashMap<Expression, Set<Constant>>();
for (Criteria criteria : crits) {
+ if (criteria instanceof CompareCriteria) {
+ CompareCriteria cc = (CompareCriteria)criteria;
+ if (cc.getOperator() != CompareCriteria.EQ) {
+ continue;
+ }
+ if (cc.getLeftExpression() instanceof Constant) {
+ inMap.put(cc.getRightExpression(), new TreeSet<Constant>(Arrays.asList((Constant)cc.getLeftExpression())));
+ } else if (cc.getRightExpression() instanceof Constant) {
+ inMap.put(cc.getLeftExpression(), new TreeSet<Constant>(Arrays.asList((Constant)cc.getRightExpression())));
+ }
+ continue;
+ }
if (!(criteria instanceof SetCriteria)) {
continue;
}
@@ -143,7 +157,7 @@
if (ex instanceof Constant) {
result.put(projectedSymbols.get(i), Collections.singleton((Constant)ex));
} else {
- TreeSet<Constant> values = inMap.get(ex);
+ Set<Constant> values = inMap.get(ex);
if (values != null) {
result.put(projectedSymbols.get(i), values);
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2010-12-22 16:13:59 UTC (rev 2791)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2010-12-23 01:51:14 UTC (rev 2792)
@@ -117,7 +117,7 @@
// Source node properties
SYMBOL_MAP, // SymbolMap
- PARTITION_INFO, // Map<ElementSymbol, List<Set<Constant>>>
+ PARTITION_INFO, // Map<ElementSymbol, List<Set<Constant>>> - it will only be consistent in the initial stages of planning
VIRTUAL_COMMAND, // Command
MAKE_DEP, // ??? List of Groups ???
PROCESSOR_PLAN, // ProcessorPlan for non-relational sub plan
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2010-12-22 16:13:59 UTC (rev 2791)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2010-12-23 01:51:14 UTC (rev 2792)
@@ -41,6 +41,7 @@
import org.teiid.query.optimizer.relational.plantree.NodeConstants;
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.lang.OrderByItem;
@@ -68,10 +69,10 @@
CommandContext context) throws QueryPlannerException,
QueryMetadataException,
TeiidComponentException {
-
+ boolean beforeDecomposeJoin = rules.contains(RuleConstants.DECOMPOSE_JOIN);
for (PlanNode sourceNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE)) {
if (sourceNode.getChildCount() > 0) {
- plan = doMerge(sourceNode, plan, metadata);
+ plan = doMerge(sourceNode, plan, beforeDecomposeJoin, metadata);
}
}
@@ -79,7 +80,7 @@
}
static PlanNode doMerge(PlanNode frame,
- PlanNode root,
+ PlanNode root, boolean beforeDecomposeJoin,
QueryMetadataInterface metadata) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
GroupSymbol virtualGroup = frame.getGroups().iterator().next();
@@ -149,6 +150,13 @@
|| NodeEditor.findNodePreOrder(frame.getFirstChild(), NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE
| NodeConstants.Types.JOIN) != null
|| NodeEditor.findAllNodes(frame.getFirstChild(), NodeConstants.Types.SOURCE, NodeConstants.Types.SOURCE).isEmpty()) {
+
+ PlanNode parentSource = NodeEditor.findParent(parentProject, NodeConstants.Types.SOURCE);
+ if (beforeDecomposeJoin && parentSource != null && parentSource.hasProperty(Info.PARTITION_INFO)
+ && !NodeEditor.findAllNodes(frame.getFirstChild(), NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE).isEmpty()) {
+ return root; //don't bother to merge until after
+ }
+
return checkForSimpleProjection(frame, root, parentProject, metadata);
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2010-12-22 16:13:59 UTC (rev 2791)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2010-12-23 01:51:14 UTC (rev 2792)
@@ -272,7 +272,7 @@
LinkedList<PlanNode> unionChildren, SymbolMap parentMap, CommandContext context, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
// remove the group node
groupNode.getParent().replaceChild(groupNode, groupNode.getFirstChild());
- GroupSymbol group = sourceNode.getGroups().iterator().next();
+ GroupSymbol group = sourceNode.getGroups().iterator().next().clone();
boolean first = true;
List<SingleElementSymbol> symbols = null;
@@ -306,11 +306,11 @@
}
}
}
-
- SymbolMap symbolMap = createSymbolMap(group, symbols, sourceNode, metadata);
+ GroupSymbol modifiedGroup = group.clone();
+ SymbolMap symbolMap = createSymbolMap(modifiedGroup, symbols, sourceNode, metadata);
sourceNode.setProperty(Info.SYMBOL_MAP, symbolMap);
- FrameUtil.convertFrame(sourceNode, group, Collections.singleton(group), symbolMap.inserseMapping(), metadata);
+ FrameUtil.convertFrame(sourceNode, group, Collections.singleton(modifiedGroup), symbolMap.inserseMapping(), metadata);
}
private boolean canPushGroupByToUnionChild(QueryMetadataInterface metadata,
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java 2010-12-22 16:13:59 UTC (rev 2791)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java 2010-12-23 01:51:14 UTC (rev 2792)
@@ -203,7 +203,7 @@
PlanNode sourceNode = NodeEditor.findParent(grandParent.getFirstChild(), NodeConstants.Types.SOURCE, NodeConstants.Types.SET_OP);
if (sourceNode != null) {
- return RuleMergeVirtual.doMerge(sourceNode, rootNode, metadata);
+ return RuleMergeVirtual.doMerge(sourceNode, rootNode, false, metadata);
}
return null;
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java 2010-12-22 16:13:59 UTC (rev 2791)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java 2010-12-23 01:51:14 UTC (rev 2792)
@@ -230,5 +230,29 @@
});
}
-
+ @Test public void testUnionPartitionedWithMerge() throws Exception {
+ //"select max(intnum) from (select * from (SELECT IntKey, intnum FROM BQT1.SmallA where intkey in (1, 2) UNION ALL SELECT intkey, intnum FROM BQT2.SmallA where intkey in (3, 4)) A where intkey in (1, 2, 3, 4) UNION ALL select intkey, intnum from bqt2.smallb where intkey in 6) B group by intkey"
+ ProcessorPlan plan = TestOptimizer.helpPlan("select * from (select * from (SELECT IntKey, intnum FROM BQT1.SmallA UNION ALL SELECT intkey, intnum FROM BQT2.SmallA) A where intkey in (1, 2, 3, 4) UNION ALL select intkey, intnum from bqt2.smallb where intkey in (6)) B inner join (SELECT IntKey, intnum FROM BQT1.SmallA where intkey in (1, 2) UNION ALL SELECT intkey, intnum FROM BQT2.SmallA where intkey in (5, 6)) C on b.intkey = c.intkey", FakeMetadataFactory.exampleBQTCached(), null, TestInlineView.getInliveViewCapabilitiesFinder(),//$NON-NLS-1$
+ new String[] { "SELECT g_0.intkey, g_0.intnum FROM BQT2.SmallA AS g_0 WHERE g_0.intkey IN (1, 2)",
+ "SELECT g_0.IntKey, g_0.intnum FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey IN (1, 2)",
+ "SELECT g_1.IntKey, g_1.IntNum, g_0.intkey, g_0.intnum FROM bqt2.smallb AS g_0, BQT2.SmallA AS g_1 WHERE (g_0.intkey = g_1.IntKey) AND (g_0.intkey = 6) AND (g_1.IntKey = 6)",
+ "SELECT g_0.IntKey AS c_0, g_0.IntNum AS c_1 FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey IN (1, 2) ORDER BY c_0" }, ComparisonMode.EXACT_COMMAND_STRING);
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 4, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 0, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 1, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 2 // UnionAll
+ });
+ }
}
14 years
teiid SVN: r2791 - in trunk: documentation/reference/src/main/docbook/en-US/content and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2010-12-22 11:13:59 -0500 (Wed, 22 Dec 2010)
New Revision: 2791
Modified:
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAccessPatternValidation.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
trunk/engine/src/main/java/org/teiid/query/sql/util/SymbolMap.java
trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
Log:
TEIID-1376 adding support for partition wise aggregation
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-22 16:13:59 UTC (rev 2791)
@@ -35,8 +35,8 @@
<LI><B>UDF</B> - new API objects added to teiid-api to support user defined functions that are capable of pushdown to source.
<LI><B>Unescape Function</B> - a new system function, unescape, was added to handle common \ escaping in strings including octal, hex/unicode, \b, \r, \n, \f, and \t.
<LI><B>Predicate Optimization</B> - expanded optimizations for detecting always false conditions when using IS NULL, IN, or comparison predicates with literal values.
- <LI><B>Partition-wise Joins</B> - Views defined by partitioned unions (union alls where each branch has a projected literal or an IN predicate that makes its values mutually exclusive from the other branches) can
- be joined against other partitioned unions and the optimizer will reorganize the join of unions into a union of joins.
+ <LI><B>Partition-wise Optimizations</B> - Views defined by partitioned unions (union alls where each branch has a projected literal or an IN predicate that makes its values mutually exclusive from the other branches) can
+ be used in aggregation or joins and the optimizer will take advantage of the partitioning information. For example, when a partitioned union is joined against another partitioned union, the optimizer will reorganize the join of unions into a union of joins.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml 2010-12-22 16:13:59 UTC (rev 2791)
@@ -38,8 +38,7 @@
These rules may trigger in turn trigger the execution of more
rules. Within several rules, Teiid also takes advantage of
costing information. The logical plan optimization steps can
- be seen by using the
- <link linkend="option_clause">OPTION DEBUG</link>
+ be seen by using <link linkend="show_plan">SHOWPLAN DEBUG</link>
clause and are described in the
<link linkend="query_planner">query planner</link>
section.
@@ -208,7 +207,7 @@
especially helpful when querying through large intermediate view
layers.</para>
</section>
- <section>
+ <section id="aggregate_pushdown">
<title>Partial Aggregate Pushdown</title>
<para> Partial aggregate pushdown allows for grouping operations
above multi-source joins and unions to be decomposed so that some of the
@@ -254,7 +253,7 @@
For example the view definition "select 1 as x, y from foo union all select z, a from foo1 where z in (2, 3)" would be considered partitioned on column x,
since the first branch can only be the value 1 and the second branch can only be the values 2 or 3.
Note that more advanced or explicit partition could be considered in the future.
- The concept of a partitioned union is used for performing partition-wise joins and in <xref linkend="updatable_views"/>.
+ The concept of a partitioned union is used for performing partition-wise joins, in <xref linkend="updatable_views"/>, and <xref linkend="aggregate_pushdown"/>.
</para>
</section>
<section id="standard_relational_techniques">
@@ -316,7 +315,7 @@
engine for executing a command submitted by a user or application.
The purpose of the query plan is to execute the user's query in as
efficient a way as possible.</para>
- <section>
+ <section id="show_plan">
<title>Getting a Query Plan</title>
<para> You can get a query plan any time you execute a command.
The SQL options available are as follows:</para>
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -69,6 +69,7 @@
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.relational.RelationalPlan;
import org.teiid.query.processor.relational.JoinNode.JoinStrategyType;
+import org.teiid.query.resolver.ProcedureContainerResolver;
import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.util.BindVariableVisitor;
import org.teiid.query.resolver.util.ResolverUtil;
@@ -120,6 +121,7 @@
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.util.CommandContext;
import org.teiid.query.validator.ValidationVisitor;
+import org.teiid.query.validator.UpdateValidator.UpdateInfo;
/**
@@ -777,6 +779,10 @@
}
node.addGroup(group);
if (nestedCommand != null) {
+ UpdateInfo info = ProcedureContainerResolver.getUpdateInfo(group, metadata);
+ if (info != null && info.getPartitionInfo() != null && !info.getPartitionInfo().isEmpty()) {
+ node.setProperty(NodeConstants.Info.PARTITION_INFO, info.getPartitionInfo());
+ }
addNestedCommand(node, group, nestedCommand, nestedCommand, true);
}
parent.addLastChild(node);
@@ -816,6 +822,12 @@
}
node.addGroup(group);
addNestedCommand(node, group, nestedCommand, nestedCommand, true);
+ if (nestedCommand instanceof SetQuery) {
+ Map<ElementSymbol, List<Set<Constant>>> partitionInfo = PartitionAnalyzer.extractPartionInfo((SetQuery)nestedCommand, ResolverUtil.resolveElementsInGroup(group, metadata));
+ if (!partitionInfo.isEmpty()) {
+ node.setProperty(NodeConstants.Info.PARTITION_INFO, partitionInfo);
+ }
+ }
hints.hasVirtualGroups = true;
parent.addLastChild(node);
} else if (clause instanceof TableFunctionReference) {
@@ -886,11 +898,6 @@
List<SingleElementSymbol> projectCols = nestedCommand.getProjectedSymbols();
SymbolMap map = SymbolMap.createSymbolMap(group, projectCols, metadata);
node.setProperty(NodeConstants.Info.SYMBOL_MAP, map);
- if (nestedCommand instanceof SetQuery) {
- //TODO: should cache for views
- Map<ElementSymbol, List<Set<Constant>>> partitionInfo = PartitionAnalyzer.extractPartionInfo((SetQuery)nestedCommand, map.getKeys());
- node.setProperty(NodeConstants.Info.PARTITION_INFO, partitionInfo);
- }
} else {
QueryMetadataInterface actualMetadata = metadata;
if (actualMetadata instanceof TempMetadataAdapter) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAccessPatternValidation.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAccessPatternValidation.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAccessPatternValidation.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -23,7 +23,6 @@
package org.teiid.query.optimizer.relational.rules;
import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
import org.teiid.api.exception.query.QueryPlannerException;
@@ -39,6 +38,7 @@
import org.teiid.query.sql.lang.Delete;
import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.lang.Update;
+import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.util.CommandContext;
@@ -102,11 +102,8 @@
List accessPatterns = (List)node.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
if (criteria != null) {
- List crits = Criteria.separateCriteriaByAnd(criteria);
-
- for(Iterator i = crits.iterator(); i.hasNext();) {
- Criteria crit = (Criteria)i.next();
- Collection elements = ElementCollectorVisitor.getElements(crit, true);
+ for(Criteria crit : Criteria.separateCriteriaByAnd(criteria)) {
+ Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(crit, true);
if (RulePushSelectCriteria.satisfyAccessPatterns(accessPatterns, elements)) {
return;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -168,7 +168,7 @@
private static AtomicInteger EXPRESSION_INDEX = new AtomicInteger(0);
- public static List<SingleElementSymbol> createExpressionSymbols(List<Expression> expressions) {
+ public static List<SingleElementSymbol> createExpressionSymbols(List<? extends Expression> expressions) {
HashMap<Expression, ExpressionSymbol> uniqueExpressions = new HashMap<Expression, ExpressionSymbol>();
List<SingleElementSymbol> result = new ArrayList<SingleElementSymbol>();
for (Expression expression : expressions) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -51,7 +51,6 @@
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.Select;
-import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
@@ -87,49 +86,45 @@
throws QueryPlannerException, QueryMetadataException,
TeiidComponentException {
- for (PlanNode unionNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SET_OP, NodeConstants.Types.SET_OP | NodeConstants.Types.ACCESS)) {
- plan = decomposeJoin(unionNode, plan, metadata, context);
+ for (PlanNode joinNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.JOIN, NodeConstants.Types.ACCESS)) {
+ plan = decomposeJoin(joinNode, plan, metadata, context);
}
return plan;
}
- public PlanNode decomposeJoin(PlanNode unionNode, PlanNode root, QueryMetadataInterface metadata, CommandContext context) throws TeiidComponentException, QueryPlannerException {
- Operation op = (Operation)unionNode.getProperty(NodeConstants.Info.SET_OPERATION);
-
- if (op != Operation.UNION
- || unionNode.getParent() == null
- || unionNode.getParent().getType() != NodeConstants.Types.SOURCE
- || unionNode.getParent().getParent().getType() != NodeConstants.Types.JOIN) {
- return root;
- }
-
- PlanNode joinNode = unionNode.getParent().getParent();
-
+ public PlanNode decomposeJoin(PlanNode joinNode, PlanNode root, QueryMetadataInterface metadata, CommandContext context) throws TeiidComponentException, QueryPlannerException {
//TODO: should be done based upon join region to allow more than a 2-way non-ansi join
-
JoinType joinType = (JoinType)joinNode.getProperty(Info.JOIN_TYPE);
if (joinType != JoinType.JOIN_INNER) {
return root;
}
+
+ PlanNode left = joinNode.getFirstChild();
+ if (left.getType() != NodeConstants.Types.SOURCE) {
+ return root;
+ }
- Map<ElementSymbol, List<Set<Constant>>> partitionInfo = (Map<ElementSymbol, List<Set<Constant>>>)unionNode.getParent().getProperty(Info.PARTITION_INFO);
+ Map<ElementSymbol, List<Set<Constant>>> partitionInfo = (Map<ElementSymbol, List<Set<Constant>>>)left.getProperty(Info.PARTITION_INFO);
if (partitionInfo == null) {
return root;
}
+
+ PlanNode unionNode = left.getFirstChild();
+ if (unionNode.getType() != NodeConstants.Types.SET_OP) {
+ return root;
+ }
- boolean left = unionNode == unionNode.getParent().getFirstChild();
+ PlanNode right = joinNode.getLastChild();
- PlanNode otherSide = left?joinNode.getLastChild():joinNode.getFirstChild();
-
- if (otherSide.getType() != NodeConstants.Types.SOURCE) {
+ if (right.getType() != NodeConstants.Types.SOURCE) {
return root;
}
- Map<ElementSymbol, List<Set<Constant>>> partitionInfoOther = (Map<ElementSymbol, List<Set<Constant>>>)otherSide.getProperty(Info.PARTITION_INFO);
+ Map<ElementSymbol, List<Set<Constant>>> rightPartionInfo = (Map<ElementSymbol, List<Set<Constant>>>)right.getProperty(Info.PARTITION_INFO);
- if (partitionInfoOther == null) {
+ if (rightPartionInfo == null) {
return root;
}
@@ -137,20 +132,20 @@
List<Expression> expr = new ArrayList<Expression>();
List<Expression> exprOther = new ArrayList<Expression>();
- RuleChooseJoinStrategy.separateCriteria(unionNode.getParent().getGroups(), otherSide.getGroups(), expr, exprOther, criteria, new LinkedList<Criteria>());
+ RuleChooseJoinStrategy.separateCriteria(unionNode.getParent().getGroups(), right.getGroups(), expr, exprOther, criteria, new LinkedList<Criteria>());
if (expr.isEmpty()) {
return root; //no equi-join
}
- List<int[]> matches = findMatches(partitionInfo, partitionInfoOther, expr, exprOther);
+ List<int[]> matches = findMatches(partitionInfo, rightPartionInfo, expr, exprOther);
if (matches == null) {
return root; //no non-overlapping partitions
}
int branchSize = partitionInfo.values().iterator().next().size();
- int otherBranchSize = partitionInfoOther.values().iterator().next().size();
+ int otherBranchSize = rightPartionInfo.values().iterator().next().size();
if (matches.isEmpty()) {
//no matches mean that we can just insert a null node (false criteria) and be done with it
@@ -161,6 +156,7 @@
}
List<PlanNode> branches = new ArrayList<PlanNode>();
+ //TODO: find union children from RulePushAggregates
RulePushSelectCriteria.collectUnionChildren(unionNode, branches);
if (branches.size() != branchSize) {
@@ -168,20 +164,20 @@
}
List<PlanNode> otherBranches = new ArrayList<PlanNode>();
- RulePushSelectCriteria.collectUnionChildren(otherSide.getFirstChild(), otherBranches);
+ RulePushSelectCriteria.collectUnionChildren(right.getFirstChild(), otherBranches);
if (otherBranches.size() != otherBranchSize) {
return root; //sanity check
}
- PlanNode newUnion = buildUnion(unionNode, otherSide, criteria, matches, branches, otherBranches);
- PlanNode view = rebuild(unionNode, metadata, context, joinNode, otherSide, newUnion);
+ PlanNode newUnion = buildUnion(unionNode, right, criteria, matches, branches, otherBranches);
+ PlanNode view = rebuild(left.getGroups().iterator().next(), joinNode, newUnion, metadata, context, left, right);
SymbolMap symbolmap = (SymbolMap)view.getProperty(Info.SYMBOL_MAP);
HashMap<ElementSymbol, List<Set<Constant>>> newPartitionInfo = new LinkedHashMap<ElementSymbol, List<Set<Constant>>>();
for (int[] match : matches) {
updatePartitionInfo(partitionInfo, matches, symbolmap, newPartitionInfo, 0, match[0]);
- updatePartitionInfo(partitionInfoOther, matches, symbolmap, newPartitionInfo, partitionInfo.size(), match[1]);
+ updatePartitionInfo(rightPartionInfo, matches, symbolmap, newPartitionInfo, partitionInfo.size(), match[1]);
}
view.setProperty(Info.PARTITION_INFO, newPartitionInfo);
@@ -207,9 +203,8 @@
/**
* Add the new union back in under a view
*/
- private PlanNode rebuild(PlanNode unionNode,
- QueryMetadataInterface metadata, CommandContext context,
- PlanNode joinNode, PlanNode otherSide, PlanNode newUnion)
+ static PlanNode rebuild(GroupSymbol group, PlanNode toReplace, PlanNode newUnion, QueryMetadataInterface metadata, CommandContext context,
+ PlanNode... toMap)
throws TeiidComponentException, QueryPlannerException,
QueryMetadataException {
Set<String> groups = context.getGroups();
@@ -218,7 +213,6 @@
context.setGroups(groups);
}
- GroupSymbol group = unionNode.getParent().getGroups().iterator().next();
group = RulePlaceAccess.recontextSymbol(group, groups);
PlanNode projectNode = NodeEditor.findNodePreOrder(newUnion, NodeConstants.Types.PROJECT);
@@ -228,16 +222,13 @@
SymbolMap newSymbolMap = (SymbolMap)view.getProperty(Info.SYMBOL_MAP);
- HashMap<ElementSymbol, ElementSymbol> inverseMap = new HashMap<ElementSymbol, ElementSymbol>();
- List<ElementSymbol> viewSymbols = newSymbolMap.getKeys();
- for (int i = 0; i < projectedSymbols.size(); i++) {
- inverseMap.put((ElementSymbol)SymbolMap.getExpression(projectedSymbols.get(i)), viewSymbols.get(i));
+ Map<Expression, ElementSymbol> inverseMap = newSymbolMap.inserseMapping();
+ toReplace.getParent().replaceChild(toReplace, view);
+ Set<GroupSymbol> newGroups = Collections.singleton(group);
+ for (PlanNode node : toMap) {
+ FrameUtil.convertFrame(view, node.getGroups().iterator().next(), newGroups, inverseMap, metadata);
}
- joinNode.getParent().replaceChild(joinNode, view);
- FrameUtil.convertFrame(view, unionNode.getParent().getGroups().iterator().next(), Collections.singleton(group), inverseMap, metadata);
- FrameUtil.convertFrame(view, otherSide.getGroups().iterator().next(), Collections.singleton(group), inverseMap, metadata);
-
return view;
}
@@ -302,14 +293,12 @@
for (int i = 0; i < matches.size(); i++) {
int[] is = matches.get(i);
PlanNode branch = branches.get(is[0]);
- PlanNode branchSource = createSource(unionNode, symbolMap);
+ PlanNode branchSource = createSource(unionNode.getParent().getGroups().iterator().next(), branch, symbolMap);
PlanNode otherBranch = otherBranches.get(is[1]);
- PlanNode otherBranchSource = createSource(otherSide.getFirstChild(), otherSymbolMap);
+ PlanNode otherBranchSource = createSource(otherSide.getGroups().iterator().next(), otherBranch, otherSymbolMap);
PlanNode newJoinNode = NodeFactory.getNewNode(NodeConstants.Types.JOIN);
- branchSource.addFirstChild(branch);
- otherBranchSource.addFirstChild(otherBranch);
newJoinNode.addLastChild(branchSource);
newJoinNode.addLastChild(otherBranchSource);
@@ -337,11 +326,12 @@
return newUnion;
}
- private PlanNode createSource(PlanNode unionNode, SymbolMap symbolMap) {
+ static PlanNode createSource(GroupSymbol group, PlanNode unionNode, SymbolMap symbolMap) {
PlanNode branchSource = NodeFactory.getNewNode(NodeConstants.Types.SOURCE);
- branchSource.addGroups(unionNode.getParent().getGroups());
+ branchSource.addGroup(group);
PlanNode projectNode = NodeEditor.findNodePreOrder(unionNode, NodeConstants.Types.PROJECT);
branchSource.setProperty(Info.SYMBOL_MAP, SymbolMap.createSymbolMap(symbolMap.getKeys(), (List<? extends SingleElementSymbol>)projectNode.getProperty(Info.PROJECT_COLS)));
+ unionNode.addAsParent(branchSource);
return branchSource;
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -58,6 +58,7 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.rewriter.QueryRewriter;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageObject.Util;
import org.teiid.query.sql.lang.CompareCriteria;
import org.teiid.query.sql.lang.Criteria;
@@ -116,7 +117,7 @@
PlanNode setOp = child.getFirstChild();
try {
- pushGroupNodeOverUnion(plan, metadata, capFinder, groupNode, child, groupingExpressions, setOp);
+ pushGroupNodeOverUnion(plan, metadata, capFinder, groupNode, child, groupingExpressions, setOp, context);
} catch (QueryResolverException e) {
throw new TeiidComponentException(e);
}
@@ -154,14 +155,26 @@
* source
* child 1
* ...
- *
+ *
* Or if the child does not support pushdown we add dummy aggregate projection
* count(*) = 1, count(x) = case x is null then 0 else 1 end, avg(x) = x, etc.
+ *
+ * if partitioned, then we don't need decomposition or the top level group by
+ *
+ * source
+ * set op
+ * project
+ * [select]
+ * group [agg(x), {a, b}]
+ * source
+ * child 1
+ * ...
+ *
*/
private void pushGroupNodeOverUnion(PlanNode plan,
QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
PlanNode groupNode, PlanNode child,
- List<SingleElementSymbol> groupingExpressions, PlanNode setOp)
+ List<SingleElementSymbol> groupingExpressions, PlanNode setOp, CommandContext context)
throws TeiidComponentException, QueryMetadataException,
QueryPlannerException, QueryResolverException {
if (setOp == null || setOp.getType() != NodeConstants.Types.SET_OP || setOp.getProperty(NodeConstants.Info.SET_OPERATION) != Operation.UNION) {
@@ -169,6 +182,22 @@
}
LinkedHashSet<AggregateSymbol> aggregates = collectAggregates(groupNode);
+ Map<ElementSymbol, List<Set<Constant>>> partitionInfo = (Map<ElementSymbol, List<Set<Constant>>>)child.getProperty(Info.PARTITION_INFO);
+
+ //check to see if any aggregate is dependent upon cardinality
+ boolean cardinalityDependent = RuleRemoveOptionalJoins.areAggregatesCardinalityDependent(aggregates);
+
+ LinkedList<PlanNode> unionChildren = new LinkedList<PlanNode>();
+ findUnionChildren(unionChildren, cardinalityDependent, setOp);
+
+ SymbolMap parentMap = (SymbolMap)child.getProperty(NodeConstants.Info.SYMBOL_MAP);
+
+ //partitioned union
+ if (partitionInfo != null && !Collections.disjoint(partitionInfo.keySet(), groupingExpressions)) {
+ decomposeGroupBy(groupNode, child, groupingExpressions, aggregates, unionChildren, parentMap, context, metadata, capFinder);
+ return;
+ }
+
/*
* if there are no aggregates, this is just duplicate removal
* mark the union as not all, which should be removed later but
@@ -181,17 +210,12 @@
return;
}
- //check to see if any aggregate is dependent upon cardinality
- boolean cardinalityDependent = RuleRemoveOptionalJoins.areAggregatesCardinalityDependent(aggregates);
+ //TODO: merge virtual, plan unions, raise null - change the partition information
- LinkedList<PlanNode> unionChildren = new LinkedList<PlanNode>();
- findUnionChildren(unionChildren, cardinalityDependent, setOp);
-
if (unionChildren.size() < 2) {
return;
}
- SymbolMap parentMap = (SymbolMap)child.getProperty(NodeConstants.Info.SYMBOL_MAP);
List<ElementSymbol> virtualElements = parentMap.getKeys();
List<SingleElementSymbol> copy = new ArrayList<SingleElementSymbol>(aggregates);
aggregates.clear();
@@ -242,6 +266,53 @@
mapExpressions(groupNode.getParent(), aggMap, metadata);
}
+ private void decomposeGroupBy(PlanNode groupNode, PlanNode sourceNode,
+ List<SingleElementSymbol> groupingExpressions,
+ LinkedHashSet<AggregateSymbol> aggregates,
+ LinkedList<PlanNode> unionChildren, SymbolMap parentMap, CommandContext context, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+ // remove the group node
+ groupNode.getParent().replaceChild(groupNode, groupNode.getFirstChild());
+ GroupSymbol group = sourceNode.getGroups().iterator().next();
+
+ boolean first = true;
+ List<SingleElementSymbol> symbols = null;
+ for (PlanNode planNode : unionChildren) {
+ PlanNode groupClone = NodeFactory.getNewNode(NodeConstants.Types.GROUP);
+ groupClone.setProperty(Info.GROUP_COLS, LanguageObject.Util.deepClone(groupingExpressions, SingleElementSymbol.class));
+ groupClone.addGroups(groupNode.getGroups());
+
+ PlanNode view = RuleDecomposeJoin.createSource(group, planNode, parentMap);
+
+ view.addAsParent(groupClone);
+
+ PlanNode projectPlanNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
+
+ Select allSymbols = new Select(groupingExpressions);
+ allSymbols.addSymbols(aggregates);
+ if (first) {
+ first = false;
+ QueryRewriter.makeSelectUnique(allSymbols, false);
+ symbols = allSymbols.getSymbols();
+ }
+ projectPlanNode.setProperty(NodeConstants.Info.PROJECT_COLS, allSymbols.getSymbols());
+ projectPlanNode.addGroups(view.getGroups());
+
+ groupClone.addAsParent(projectPlanNode);
+
+ if (planNode.getType() == NodeConstants.Types.ACCESS) {
+ //TODO: temporarily remove the access node so that the inline view could be removed if possible
+ while (RuleRaiseAccess.raiseAccessNode(planNode, planNode, metadata, capFinder, true, null) != null) {
+ //continue to raise
+ }
+ }
+ }
+
+ SymbolMap symbolMap = createSymbolMap(group, symbols, sourceNode, metadata);
+ sourceNode.setProperty(Info.SYMBOL_MAP, symbolMap);
+
+ FrameUtil.convertFrame(sourceNode, group, Collections.singleton(group), symbolMap.inserseMapping(), metadata);
+ }
+
private boolean canPushGroupByToUnionChild(QueryMetadataInterface metadata,
CapabilitiesFinder capFinder,
List<SingleElementSymbol> groupingExpressions,
@@ -270,7 +341,7 @@
/**
* Recursively searches the union tree for all applicable source nodes
*/
- private PlanNode findUnionChildren(List<PlanNode> unionChildren, boolean carinalityDependent, PlanNode setOp) {
+ static PlanNode findUnionChildren(List<PlanNode> unionChildren, boolean carinalityDependent, PlanNode setOp) {
if (setOp.getType() != NodeConstants.Types.SET_OP || setOp.getProperty(NodeConstants.Info.SET_OPERATION) != Operation.UNION) {
return setOp;
}
@@ -383,20 +454,28 @@
static PlanNode createView(GroupSymbol group, List<? extends SingleElementSymbol> virtualElements, PlanNode child, QueryMetadataInterface metadata) throws TeiidComponentException {
PlanNode intermediateView = NodeFactory.getNewNode(NodeConstants.Types.SOURCE);
- TempMetadataStore store = new TempMetadataStore();
+ SymbolMap symbolMap = createSymbolMap(group, virtualElements, child, metadata);
+ intermediateView.setProperty(NodeConstants.Info.SYMBOL_MAP, symbolMap);
+ child.addAsParent(intermediateView);
+ intermediateView.addGroup(group);
+ return intermediateView;
+ }
+
+ private static SymbolMap createSymbolMap(GroupSymbol group,
+ List<? extends SingleElementSymbol> virtualElements,
+ PlanNode child, QueryMetadataInterface metadata)
+ throws TeiidComponentException, QueryMetadataException {
+ TempMetadataStore store = new TempMetadataStore();
TempMetadataAdapter tma = new TempMetadataAdapter(metadata, store);
try {
group.setMetadataID(ResolverUtil.addTempGroup(tma, group, virtualElements, false));
} catch (QueryResolverException e) {
throw new TeiidComponentException(e);
}
- intermediateView.addGroup(group);
List<ElementSymbol> projectedSymbols = ResolverUtil.resolveElementsInGroup(group, metadata);
SymbolMap symbolMap = SymbolMap.createSymbolMap(projectedSymbols,
(List<Expression>)NodeEditor.findNodePreOrder(child, NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS));
- intermediateView.setProperty(NodeConstants.Info.SYMBOL_MAP, symbolMap);
- child.addAsParent(intermediateView);
- return intermediateView;
+ return symbolMap;
}
private void updateSymbolName(List<SingleElementSymbol> projectCols, int i,
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -245,15 +245,37 @@
}
public static UpdateInfo getUpdateInfo(GroupSymbol group, QueryMetadataInterface metadata, int type) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
+ UpdateInfo info = getUpdateInfo(group, metadata);
+
+ if (info == null) {
+ return null;
+ }
+
+ if ((info.isDeleteValidationError() && type == Command.TYPE_DELETE)
+ || (info.isUpdateValidationError() && type == Command.TYPE_UPDATE)
+ || (info.isInsertValidationError() && type == Command.TYPE_INSERT)) {
+ String name = "Delete"; //$NON-NLS-1$
+ if (type == Command.TYPE_UPDATE) {
+ name = "Update"; //$NON-NLS-1$
+ } else if (type == Command.TYPE_INSERT) {
+ name = "Insert"; //$NON-NLS-1$
+ }
+ throw new QueryResolverException("ERR.015.008.0009", QueryPlugin.Util.getString("ERR.015.008.0009", group, name)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return info;
+ }
+
+ public static UpdateInfo getUpdateInfo(GroupSymbol group,
+ QueryMetadataInterface metadata) throws TeiidComponentException,
+ QueryMetadataException, QueryResolverException {
//if this is not a view, just return null
- if(group.isTempGroupSymbol() || !metadata.isVirtualGroup(group.getMetadataID())) {
+ if(group.isTempGroupSymbol() || !metadata.isVirtualGroup(group.getMetadataID()) || !metadata.isVirtualModel(metadata.getModelID(group.getMetadataID()))) {
return null;
}
String updatePlan = metadata.getUpdatePlan(group.getMetadataID());
String deletePlan = metadata.getDeletePlan(group.getMetadataID());
String insertPlan = metadata.getInsertPlan(group.getMetadataID());
-
UpdateInfo info = (UpdateInfo)metadata.getFromMetadataCache(group.getMetadataID(), "UpdateInfo"); //$NON-NLS-1$
if (info == null) {
List<ElementSymbol> elements = ResolverUtil.resolveElementsInGroup(group, metadata);
@@ -264,19 +286,7 @@
}
metadata.addToMetadataCache(group.getMetadataID(), "UpdateInfo", info); //$NON-NLS-1$
}
-
- if ((info.isDeleteValidationError() && type == Command.TYPE_DELETE)
- || (info.isUpdateValidationError() && type == Command.TYPE_UPDATE)
- || (info.isInsertValidationError() && type == Command.TYPE_INSERT)) {
- String name = "Delete"; //$NON-NLS-1$
- if (type == Command.TYPE_UPDATE) {
- name = "Update"; //$NON-NLS-1$
- } else if (type == Command.TYPE_INSERT) {
- name = "Insert"; //$NON-NLS-1$
- }
- throw new QueryResolverException("ERR.015.008.0009", QueryPlugin.Util.getString("ERR.015.008.0009", group, name)); //$NON-NLS-1$ //$NON-NLS-2$
- }
- return info;
+ return info;
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/sql/util/SymbolMap.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/util/SymbolMap.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/sql/util/SymbolMap.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
@@ -59,6 +60,14 @@
return clonedMap;
}
+ public Map<Expression, ElementSymbol> inserseMapping() {
+ HashMap<Expression, ElementSymbol> inverseMap = new HashMap<Expression, ElementSymbol>();
+ for (Map.Entry<ElementSymbol, Expression> entry : this.map.entrySet()) {
+ inverseMap.put(entry.getValue(), entry.getKey());
+ }
+ return inverseMap;
+ }
+
/**
* @return true if the map did not already contained the given symbol
*/
Modified: trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -448,7 +448,7 @@
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0005"), true, false, true); //$NON-NLS-1$
}
if (this.updateInfo.deleteType == UpdateType.INHERENT && this.updateInfo.deleteTarget == null) {
- if (this.updateInfo.isSimple) {
+ if (this.updateInfo.isSimple && updatable) {
this.updateInfo.deleteTarget = this.updateInfo.updatableGroups.values().iterator().next();
} else {
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0014"), false, false, true); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -41,13 +41,13 @@
public class TestInlineView {
- public static QueryMetadataInterface createInlineViewMetadata(FakeCapabilitiesFinder capFinder) {
- QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
-
+ public static FakeCapabilitiesFinder getInliveViewCapabilitiesFinder() {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_FROM_INLINE_VIEWS, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, true);
+ caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, true);
caps.setCapabilitySupport(Capability.QUERY_SELECT_DISTINCT, true);
caps.setCapabilitySupport(Capability.QUERY_FROM_JOIN_OUTER, true);
caps.setCapabilitySupport(Capability.QUERY_UNION, true);
@@ -59,8 +59,7 @@
caps.setFunctionSupport("+", true); //$NON-NLS-1$
capFinder.addCapabilities("BQT1", caps); //$NON-NLS-1$
capFinder.addCapabilities("BQT2", caps); //$NON-NLS-1$
-
- return metadata;
+ return capFinder;
}
@Test public void testANSIJoinInlineView() throws Exception {
@@ -244,8 +243,8 @@
}
protected void runTest(InlineViewCase testCase) throws Exception {
- FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
- QueryMetadataInterface metadata = createInlineViewMetadata(capFinder);
+ FakeCapabilitiesFinder capFinder = getInliveViewCapabilitiesFinder();
+ QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
ProcessorPlan plan = TestOptimizer.helpPlan(testCase.userQuery, metadata, null, capFinder, new String[] {testCase.optimizedQuery}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING);
@@ -253,8 +252,8 @@
}
@Test public void testAliasCreationWithInlineView() {
- FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
- QueryMetadataInterface metadata = createInlineViewMetadata(capFinder);
+ FakeCapabilitiesFinder capFinder = getInliveViewCapabilitiesFinder();
+ QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
ProcessorPlan plan = helpPlan("select a, b from (select distinct count(intNum) a, count(stringKey), bqt1.smalla.intkey as b from bqt1.smalla group by bqt1.smalla.intkey) q1 order by q1.a", //$NON-NLS-1$
metadata, null, capFinder, new String[] {"SELECT COUNT(g_0.intNum) AS c_0, g_0.intkey AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey ORDER BY c_0"}, true); //$NON-NLS-1$
@@ -263,8 +262,8 @@
}
@Test public void testAliasPreservationWithInlineView() {
- FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
- QueryMetadataInterface metadata = createInlineViewMetadata(capFinder);
+ FakeCapabilitiesFinder capFinder = getInliveViewCapabilitiesFinder();
+ QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
ProcessorPlan plan = helpPlan("select q1.a + 1, q1.b from (select count(bqt1.smalla.intNum) as a, bqt1.smalla.intkey as b from bqt1.smalla group by bqt1.smalla.intNum, bqt1.smalla.intkey order by b) q1 where q1.a = 1", //$NON-NLS-1$
metadata, null, capFinder, new String[] {"SELECT (q1.a + 1), q1.b FROM (SELECT COUNT(bqt1.smalla.intNum) AS a, bqt1.smalla.intkey AS b FROM bqt1.smalla GROUP BY bqt1.smalla.intNum, bqt1.smalla.intkey HAVING COUNT(bqt1.smalla.intNum) = 1) AS q1"}, true); //$NON-NLS-1$
@@ -276,8 +275,8 @@
* Order by's will be added to the atomic queries
*/
@Test public void testCrossSourceInlineView() throws Exception {
- FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
- QueryMetadataInterface metadata = createInlineViewMetadata(capFinder);
+ FakeCapabilitiesFinder capFinder = getInliveViewCapabilitiesFinder();
+ QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
ProcessorPlan plan = helpPlan("select * from (select count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey) q1 inner join (select count(bqt2.smallb.intkey) as a, bqt2.smallb.intkey from bqt2.smallb group by bqt2.smallb.intkey) as q2 on q1.intkey = q2.intkey where q1.a = 1", //$NON-NLS-1$
metadata, null, capFinder, new String[] {"SELECT v_0.c_0, v_0.c_1 FROM (SELECT g_0.intkey AS c_0, COUNT(g_0.intkey) AS c_1 FROM bqt2.smallb AS g_0 GROUP BY g_0.intkey) AS v_0 ORDER BY c_0", //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java 2010-12-22 14:39:41 UTC (rev 2790)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java 2010-12-22 16:13:59 UTC (rev 2791)
@@ -207,4 +207,28 @@
});
}
+ @Test public void testUnionWithPartitionedAggregate() throws Exception {
+ ProcessorPlan plan = TestOptimizer.helpPlan("select max(intnum) from (SELECT IntKey, intnum FROM BQT1.SmallA where intkey in (1, 2) UNION ALL SELECT intkey, intnum FROM BQT2.SmallA where intkey in (3, 4)) A group by intkey", FakeMetadataFactory.exampleBQTCached(), null, TestInlineView.getInliveViewCapabilitiesFinder(),//$NON-NLS-1$
+ new String[] { "SELECT MAX(v_0.c_1) FROM (SELECT g_0.IntKey AS c_0, g_0.intnum AS c_1 FROM BQT1.SmallA AS g_0 WHERE g_0.intkey IN (1, 2)) AS v_0 GROUP BY v_0.c_0",
+ "SELECT MAX(v_0.c_1) FROM (SELECT g_0.intkey AS c_0, g_0.intnum AS c_1 FROM BQT2.SmallA AS g_0 WHERE g_0.intkey IN (3, 4)) AS v_0 GROUP BY v_0.c_0" }, ComparisonMode.EXACT_COMMAND_STRING);
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 0, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 0, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 1 // UnionAll
+ });
+ }
+
+
}
14 years