teiid SVN: r3334 - in branches/7.4.x/engine/src: main/java/org/teiid/query/optimizer/relational/rules and 2 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-25 14:19:13 -0400 (Mon, 25 Jul 2011)
New Revision: 3334
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
Log:
TEIID-1682 preserving sort options
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-07-25 17:39:32 UTC (rev 3333)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-07-25 18:19:13 UTC (rev 3334)
@@ -53,6 +53,7 @@
import org.teiid.query.processor.relational.DependentAccessNode;
import org.teiid.query.processor.relational.DependentProcedureAccessNode;
import org.teiid.query.processor.relational.DependentProcedureExecutionNode;
+import org.teiid.query.processor.relational.EnhancedSortMergeJoinStrategy;
import org.teiid.query.processor.relational.GroupingNode;
import org.teiid.query.processor.relational.InsertPlanExecutionNode;
import org.teiid.query.processor.relational.JoinNode;
@@ -61,7 +62,6 @@
import org.teiid.query.processor.relational.NestedLoopJoinStrategy;
import org.teiid.query.processor.relational.NestedTableJoinStrategy;
import org.teiid.query.processor.relational.NullNode;
-import org.teiid.query.processor.relational.EnhancedSortMergeJoinStrategy;
import org.teiid.query.processor.relational.PlanExecutionNode;
import org.teiid.query.processor.relational.ProjectIntoNode;
import org.teiid.query.processor.relational.ProjectNode;
@@ -93,6 +93,7 @@
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.EvaluatableVisitor;
import org.teiid.query.sql.visitor.GroupCollectorVisitor;
@@ -377,8 +378,22 @@
break;
case NodeConstants.Types.GROUP:
GroupingNode gnode = new GroupingNode(getID());
- gnode.setGroupingElements( (List) node.getProperty(NodeConstants.Info.GROUP_COLS) );
+ List<SingleElementSymbol> gCols = (List) node.getProperty(NodeConstants.Info.GROUP_COLS);
+ gnode.setGroupingElements( gCols );
gnode.setRemoveDuplicates(node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL));
+ orderBy = (OrderBy) node.getProperty(Info.SORT_ORDER);
+ if (orderBy == null) {
+ if (gCols != null) {
+ orderBy = new OrderBy(gCols);
+ }
+ } else {
+ for (int i = orderBy.getOrderByItems().size(); i < gCols.size(); i++) {
+ orderBy.addVariable(gCols.get(i), OrderBy.ASC);
+ }
+ }
+ if (orderBy != null) {
+ gnode.setOrderBy(orderBy.getOrderByItems());
+ }
processNode = gnode;
break;
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java 2011-07-25 17:39:32 UTC (rev 3333)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java 2011-07-25 18:19:13 UTC (rev 3334)
@@ -85,7 +85,8 @@
} else {
root = checkForProjectOptimization(node, root, metadata, capFinder, record);
}
- List<SingleElementSymbol> orderColumns = ((OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER)).getSortKeys();
+ OrderBy orderBy = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
+ List<SingleElementSymbol> orderColumns = orderBy.getSortKeys();
PlanNode possibleSort = NodeEditor.findNodePreOrder(node, NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE | NodeConstants.Types.ACCESS);
if (possibleSort != null) {
List exprs = (List)possibleSort.getProperty(Info.GROUP_COLS);
@@ -102,6 +103,7 @@
NodeEditor.removeChildNode(node.getParent(), node);
node = nextNode;
}
+ possibleSort.setProperty(Info.SORT_ORDER, orderBy);
}
break;
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java 2011-07-25 17:39:32 UTC (rev 3333)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java 2011-07-25 18:19:13 UTC (rev 3334)
@@ -22,12 +22,10 @@
package org.teiid.query.processor.relational;
-import static org.teiid.query.analysis.AnalysisRecord.PROP_GROUP_COLS;
-import static org.teiid.query.analysis.AnalysisRecord.PROP_SORT_MODE;
+import static org.teiid.query.analysis.AnalysisRecord.*;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -42,6 +40,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.language.SQLConstants.NonReserved;
+import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.function.aggregate.AggregateFunction;
import org.teiid.query.function.aggregate.ArrayAgg;
@@ -57,7 +56,6 @@
import org.teiid.query.processor.BatchCollector;
import org.teiid.query.processor.ProcessorDataManager;
import org.teiid.query.processor.relational.SortUtility.Mode;
-import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.ElementSymbol;
@@ -72,7 +70,7 @@
// Grouping columns set by the planner
private List sortElements;
- private List sortTypes;
+ private List<OrderByItem> orderBy;
private boolean removeDuplicates;
// Collection phase
@@ -129,10 +127,11 @@
*/
public void setGroupingElements(List groupingElements) {
this.sortElements = groupingElements;
- if(groupingElements != null) {
- sortTypes = Collections.nCopies(groupingElements.size(), Boolean.valueOf(OrderBy.ASC));
- }
}
+
+ public void setOrderBy(List<OrderByItem> orderBy) {
+ this.orderBy = orderBy;
+ }
@Override
public void initialize(CommandContext context, BufferManager bufferManager,
@@ -305,8 +304,7 @@
this.groupTupleSource = getCollectionTupleSource();
this.phase = GROUP;
} else {
- this.sortUtility = new SortUtility(getCollectionTupleSource(), sortElements,
- sortTypes, removeDuplicates?Mode.DUP_REMOVE_SORT:Mode.SORT, getBufferManager(),
+ this.sortUtility = new SortUtility(getCollectionTupleSource(), orderBy, removeDuplicates?Mode.DUP_REMOVE_SORT:Mode.SORT, getBufferManager(),
getConnectionID(), collectedExpressions);
this.phase = SORT;
}
@@ -421,8 +419,8 @@
GroupingNode clonedNode = new GroupingNode(super.getID());
super.copy(this, clonedNode);
clonedNode.sortElements = sortElements;
- clonedNode.sortTypes = sortTypes;
clonedNode.removeDuplicates = removeDuplicates;
+ clonedNode.orderBy = orderBy;
return clonedNode;
}
@@ -438,7 +436,9 @@
}
props.addProperty(PROP_GROUP_COLS, groupCols);
}
-
+ if (orderBy != null) {
+ props.addProperty(AnalysisRecord.PROP_SORT_COLS, orderBy.toString());
+ }
props.addProperty(PROP_SORT_MODE, String.valueOf(this.removeDuplicates));
return props;
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-25 17:39:32 UTC (rev 3333)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-25 18:19:13 UTC (rev 3334)
@@ -7559,5 +7559,19 @@
helpProcess(plan, dataManager, new List[] {Arrays.asList("a")});
}
+ @Test public void testSortGroupCombination() throws Exception {
+ String sql = "select e2, max(e1) from pm1.g1 x group by e2 order by e2 desc"; //$NON-NLS-1$
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+ ProcessorPlan plan = helpGetPlan(sql, RealMetadataFactory.example1Cached(), TestOptimizer.getGenericFinder());
+
+ helpProcess(plan, dataManager, new List[] {
+ Arrays.asList(3, "a"),
+ Arrays.asList(2, "b"),
+ Arrays.asList(1, "c"),
+ Arrays.asList(0, "a")});
+ }
+
private static final boolean DEBUG = false;
}
13 years, 5 months
teiid SVN: r3333 - in branches/7.4.x/engine/src: test/java/org/teiid/query/processor and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-25 13:39:32 -0400 (Mon, 25 Jul 2011)
New Revision: 3333
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushLimit.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
Log:
TEIID-1681 fix for pushing limits too far with procedure executions
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushLimit.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushLimit.java 2011-07-25 15:46:41 UTC (rev 3332)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushLimit.java 2011-07-25 17:39:32 UTC (rev 3333)
@@ -51,6 +51,7 @@
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.Function;
+import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.visitor.EvaluatableVisitor;
import org.teiid.query.util.CommandContext;
@@ -168,6 +169,13 @@
}
case NodeConstants.Types.SOURCE:
{
+ GroupSymbol virtualGroup = child.getGroups().iterator().next();
+ if (virtualGroup.isProcedure()) {
+ return false;
+ }
+ if (FrameUtil.isProcedure(child.getFirstChild())) {
+ return false;
+ }
return true;
}
default:
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-25 15:46:41 UTC (rev 3332)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-25 17:39:32 UTC (rev 3333)
@@ -7549,5 +7549,15 @@
helpProcess(plan, dataManager, new List[] {Arrays.asList(1, 1)});
}
+ @Test public void testUnorderedLimitWithProc() throws Exception {
+ String sql = "select e1 from (exec pm1.sq1()) x limit 1";
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+ ProcessorPlan plan = helpGetPlan(sql, RealMetadataFactory.example1Cached(), TestOptimizer.getGenericFinder());
+
+ helpProcess(plan, dataManager, new List[] {Arrays.asList("a")});
+ }
+
private static final boolean DEBUG = false;
}
13 years, 5 months
teiid SVN: r3332 - in branches/7.1.1.CP3: engine/src/main/java/org/teiid/cache and 7 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-07-25 11:46:41 -0400 (Mon, 25 Jul 2011)
New Revision: 3332
Modified:
branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCache.java
branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheListener.java
branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/TupleBatchCacheLoader.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/Cache.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/CacheListener.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/DefaultCache.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java
branches/7.1.1.CP3/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java
branches/7.1.1.CP3/engine/src/main/resources/org/teiid/query/i18n.properties
branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java
branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
branches/7.1.1.CP3/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
branches/7.1.1.CP3/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
Log:
TEIID-1657: Implemented distributed refreshMatView call based on the JBoss Cache Listener mechanism. When user issues a refreshMatView call on one node, then all the nodes gets notified about the change in the original node after load of the mat view table is finished. The proactive load on the passive nodes are done in a separate thread. Also fixed a memory leak with the TupleBufferCacheLoader in loading batches.
Modified: branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCache.java
===================================================================
--- branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCache.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCache.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -112,11 +112,13 @@
}
}
- public synchronized void addListener(CacheListener listener) {
- this.cacheListener = new JBossCacheListener(this.rootFqn, listener);
+ @Override
+ public synchronized void setListener(CacheListener listener) {
+ this.cacheListener = new JBossCacheListener(this.rootFqn, this.cacheStore, this, listener);
this.cacheStore.addCacheListener(this.cacheListener);
}
+ @Override
public synchronized void removeListener() {
this.cacheStore.removeCacheListener(this.cacheListener);
this.cacheListener = null;
Modified: branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheListener.java
===================================================================
--- branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheListener.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheListener.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -21,7 +21,11 @@
*/
package org.teiid.cache.jboss;
+import java.util.Set;
+
import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.eviction.ExpirationAlgorithmConfig;
import org.jboss.cache.notifications.annotation.NodeCreated;
import org.jboss.cache.notifications.annotation.NodeEvicted;
import org.jboss.cache.notifications.annotation.NodeLoaded;
@@ -33,14 +37,18 @@
@org.jboss.cache.notifications.annotation.CacheListener
-public class JBossCacheListener {
+public class JBossCacheListener<K,V> {
private CacheListener listener;
private Fqn rootFqn;
+ private JBossCache cache;
+ private org.jboss.cache.Cache<K,V> cacheStore;
- public JBossCacheListener(Fqn fqn, CacheListener listener) {
+ public JBossCacheListener(Fqn fqn, org.jboss.cache.Cache cacheStore, JBossCache cache, CacheListener listener) {
this.rootFqn = fqn;
this.listener = listener;
+ this.cache = cache;
+ this.cacheStore = cacheStore;
}
@NodeCreated
@@ -55,4 +63,61 @@
listener.cacheChanged();
}
}
+
+ @NodeCreated
+ public synchronized void cacheCreated(NodeEvent ne) {
+ if (!ne.isPre() && !ne.isOriginLocal()) {
+ Fqn fqn = ne.getFqn();
+ if (fqn.isChildOrEquals(rootFqn)) {
+ Node<K,V> node = this.cacheStore.getNode(fqn);
+ if (node != null) {
+ Set<K> keys = node.getKeys();
+ for (K key:keys) {
+ if ((key instanceof String) && (key.equals(ExpirationAlgorithmConfig.EXPIRATION_KEY))) {
+ continue;
+ }
+ listener.cacheCreated(key, cache.get(key));
+ }
+ }
+ }
+ }
+ }
+
+ @NodeRemoved
+ public synchronized void cacheRemoved(NodeEvent ne) {
+ if (!ne.isPre() && !ne.isOriginLocal()) {
+ Fqn fqn = ne.getFqn();
+ if (fqn.isChildOrEquals(rootFqn)) {
+ Node<K,V> node = this.cacheStore.getNode(fqn);
+ if (node != null) {
+ Set<K> keys = node.getKeys();
+ for (K key:keys) {
+ if ((key instanceof String) && (key.equals(ExpirationAlgorithmConfig.EXPIRATION_KEY))) {
+ continue;
+ }
+ listener.cacheRemoved(key, cache.get(key));
+ }
+ }
+ }
+ }
+ }
+
+ @NodeModified
+ public synchronized void cacheModified(NodeEvent ne) {
+ Fqn fqn = ne.getFqn();
+ if (!ne.isPre() && !ne.isOriginLocal()) {
+ if (fqn.isChildOrEquals(rootFqn)) {
+ Node<K,V> node = this.cacheStore.getNode(fqn);
+ if (node != null) {
+ Set<K> keys = node.getKeys();
+ for (K key:keys) {
+ if ((key instanceof String) && (key.equals(ExpirationAlgorithmConfig.EXPIRATION_KEY))) {
+ continue;
+ }
+ listener.cacheModified(key, cache.get(key));
+ }
+ }
+ }
+ }
+ }
}
Modified: branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/TupleBatchCacheLoader.java
===================================================================
--- branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/TupleBatchCacheLoader.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/TupleBatchCacheLoader.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -62,9 +62,8 @@
map.put(id, b);
return map;
}
- return super.get(fqn);
}
- return null;
+ return super.get(fqn);
}
@Override
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/Cache.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/Cache.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/Cache.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -82,4 +82,14 @@
* @return
*/
Set<K> keys();
+
+ /**
+ * set cache listener
+ * @param listener
+ */
+ void setListener(CacheListener<K, V> listener);
+
+
+ void removeListener();
+
}
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/CacheListener.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/CacheListener.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/CacheListener.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -25,6 +25,9 @@
/**
* Listener for the cache events like add,update delete
*/
-public interface CacheListener {
+public interface CacheListener<K, V> {
void cacheChanged();
+ void cacheCreated(K key, V value);
+ void cacheRemoved(K key, V value);
+ void cacheModified(K key, V value);
}
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/DefaultCache.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/DefaultCache.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/cache/DefaultCache.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -95,9 +95,11 @@
this.ttl = ttl;
}
- public void addListener(CacheListener listener) {
- throw new UnsupportedOperationException();
+ public void setListener(CacheListener listener) {
}
+
+ public void removeListener() {
+ }
public void clear() {
synchronized (map) {
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/common/buffer/TupleBuffer.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -95,8 +95,12 @@
this.uuid = java.util.UUID.randomUUID().toString();
}
return this.uuid;
- }
+ }
+ public void setId(String uuid) {
+ this.uuid = uuid;
+ }
+
public boolean isLobs() {
return lobIndexes != null;
}
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -130,6 +130,7 @@
}
buffer = bufferManager.createTupleBuffer(schema, "cached", TupleSourceType.FINAL); //$NON-NLS-1$
buffer.setBatchSize(this.batchSize);
+ buffer.setId(this.uuid);
if (this.hint != null) {
buffer.setPrefersMemory(this.hint.getPrefersMemory());
}
@@ -142,6 +143,7 @@
return false;
}
buffer.addTupleBatch(batch, true);
+ cache.remove(uuid+","+row); //$NON-NLS-1$
}
this.results = buffer;
bufferManager.addTupleBuffer(this.results);
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -22,6 +22,10 @@
package org.teiid.dqp.internal.process;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -46,6 +50,7 @@
import org.teiid.adminapi.impl.WorkerPoolStatisticsMetadata;
import org.teiid.cache.CacheConfiguration;
import org.teiid.cache.CacheFactory;
+import org.teiid.cache.CacheListener;
import org.teiid.cache.CacheConfiguration.Policy;
import org.teiid.client.DQP;
import org.teiid.client.RequestMessage;
@@ -212,6 +217,7 @@
private CacheFactory cacheFactory;
private SessionAwareCache<CachedResults> matTables;
+ private CacheListener<TempTableDataManager.MatTableKey, TempTableDataManager.MatTableEntry> matTableListener;
/**
* perform a full shutdown and wait for 10 seconds for all threads to finish
@@ -711,11 +717,11 @@
}
if (cacheFactory.isReplicated()) {
- matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.EXPIRATION, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
+ matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.EXPIRATION, -1, -1, "MaterializationTables")); //$NON-NLS-1$
matTables.setBufferManager(this.bufferManager);
}
- dataTierMgr = new TempTableDataManager(new DataTierManagerImpl(this,this.bufferService), this.bufferManager, this.processWorkerPool, this.rsCache, this.matTables, this.cacheFactory);
+ dataTierMgr = new TempTableDataManager(new DataTierManagerImpl(this,this.bufferService), this.bufferManager, this.processWorkerPool, this.rsCache, this.matTables, this.cacheFactory, this.matTableListener);
}
public void setBufferService(BufferService service) {
@@ -726,6 +732,29 @@
this.transactionService = service;
}
+ public void setMatTableListener(final CacheListener<TempTableDataManager.MatTableKey, TempTableDataManager.MatTableEntry> listener) {
+ this.matTableListener = (CacheListener<TempTableDataManager.MatTableKey, TempTableDataManager.MatTableEntry>)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {CacheListener.class}, new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
+ addWork(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ method.invoke(listener, args);
+ } catch (IllegalArgumentException e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, e);
+ } catch (IllegalAccessException e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, e);
+ } catch (InvocationTargetException e) {
+ LogManager.logDetail(LogConstants.CTX_DQP, e);
+ }
+ }
+ });
+ return null;
+ }
+ });
+ }
+
@Override
public boolean cancelRequest(long requestID)
throws TeiidProcessingException, TeiidComponentException {
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -32,6 +32,7 @@
import org.teiid.cache.Cache;
import org.teiid.cache.CacheConfiguration;
import org.teiid.cache.CacheFactory;
+import org.teiid.cache.CacheListener;
import org.teiid.cache.DefaultCache;
import org.teiid.cache.DefaultCacheFactory;
import org.teiid.cache.CacheConfiguration.Policy;
@@ -307,4 +308,14 @@
public void setBufferManager(BufferManager bufferManager) {
this.bufferManager = bufferManager;
}
+
+ public void setListener(CacheListener<CacheID, T> listener) {
+ this.localCache.setListener(listener);
+ this.distributedCache.setListener(listener);
+ }
+
+ public void removeListener() {
+ this.localCache.removeListener();
+ this.distributedCache.removeListener();
+ }
}
Modified: branches/7.1.1.CP3/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java
===================================================================
--- branches/7.1.1.CP3/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -40,6 +40,7 @@
import org.teiid.cache.Cache;
import org.teiid.cache.CacheConfiguration;
import org.teiid.cache.CacheFactory;
+import org.teiid.cache.CacheListener;
import org.teiid.cache.CacheConfiguration.Policy;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
@@ -113,7 +114,7 @@
private SessionAwareCache<CachedResults> cache;
private Executor executor;
- private static class MatTableKey implements Serializable {
+ public static class MatTableKey implements Serializable {
private static final long serialVersionUID = 5481692896572663992L;
String name;
VDBKey vdb;
@@ -134,19 +135,37 @@
MatTableKey other = (MatTableKey)obj;
return this.name.equals(other.name) && this.vdb.equals(other.vdb);
}
+
+ public String getVDBName() {
+ return vdb.getName();
+ }
+
+ public int getVDBVersion() {
+ return vdb.getVersion();
+ }
}
- private static class MatTableEntry implements Serializable {
+ public static class MatTableEntry implements Serializable {
private static final long serialVersionUID = 8559613701442751579L;
long lastUpdate = System.currentTimeMillis();
boolean valid;
+ String viewName;
+
+ public String getViewName() {
+ return viewName;
+ }
+
+ public boolean allowsUpdate() {
+ return valid && viewName != null;
+ }
}
private Cache<MatTableKey, MatTableEntry> tables;
+ private Cache<MatTableKey, MatTableEntry> refreshJob;
private SessionAwareCache<CachedResults> distributedCache;
public TempTableDataManager(ProcessorDataManager processorDataManager, BufferManager bufferManager,
- Executor executor, SessionAwareCache<CachedResults> cache, SessionAwareCache<CachedResults> distibutedCache, CacheFactory cacheFactory){
+ Executor executor, SessionAwareCache<CachedResults> cache, SessionAwareCache<CachedResults> distibutedCache, CacheFactory cacheFactory, CacheListener<MatTableKey, MatTableEntry> listener){
this.processorDataManager = processorDataManager;
this.bufferManager = bufferManager;
this.executor = executor;
@@ -155,6 +174,10 @@
if (distibutedCache != null) {
CacheConfiguration cc = new CacheConfiguration(Policy.LRU, -1, -1, "MaterializationUpdates"); //$NON-NLS-1$
tables = cacheFactory.get(cc.getLocation(), cc);
+
+ cc = new CacheConfiguration(Policy.LRU, -1, -1, "MaterializationRefresh"); //$NON-NLS-1$
+ refreshJob = cacheFactory.get(cc.getLocation(), cc);
+ refreshJob.setListener(listener);
}
}
@@ -289,7 +312,7 @@
context.setDeterminismLevel(determinismLevel);
return tb.createIndexedTupleSource();
}
-
+
private TupleSource handleSystemProcedures(CommandContext context, StoredProcedure proc)
throws TeiidComponentException, QueryMetadataException,
QueryProcessingException, QueryResolverException,
@@ -303,9 +326,23 @@
String matTableName = RelationalPlanner.MAT_PREFIX+matViewName.toUpperCase();
LogManager.logDetail(LogConstants.CTX_MATVIEWS, "processing refreshmatview for", matViewName); //$NON-NLS-1$
MatTableInfo info = globalStore.getMatTableInfo(matTableName);
+
+ Long loadTime = null;
+ boolean useCache = false;
+ if (this.distributedCache != null) {
+ MatTableKey key = new MatTableKey();
+ key.name = matTableName;
+ key.vdb = new VDBKey(context.getVdbName(), context.getVdbVersion());
+ MatTableEntry entry = this.tables.get(key);
+ useCache = (entry != null && entry.valid && entry.lastUpdate > info.getUpdateTime());
+ if (useCache) {
+ loadTime = entry.lastUpdate;
+ }
+ }
+
boolean invalidate = Boolean.TRUE.equals(((Constant)proc.getParameter(2).getExpression()).getValue());
if (invalidate) {
- touchTable(context, matTableName, false);
+ touchTable(context, matTableName, matViewName, false, System.currentTimeMillis());
}
MatState oldState = info.setState(MatState.NEEDS_LOADING, invalidate?Boolean.FALSE:null, null);
if (oldState == MatState.LOADING) {
@@ -316,7 +353,7 @@
Object matTableId = RelationalPlanner.getGlobalTempTableMetadataId(group, matTableName, context, metadata, AnalysisRecord.createNonRecordingRecord());
GroupSymbol matTable = new GroupSymbol(matTableName);
matTable.setMetadataID(matTableId);
- int rowCount = loadGlobalTable(context, matTable, matTableName, globalStore, info, null, false);
+ int rowCount = loadGlobalTable(context, matTable, matTableName, matViewName, globalStore, info, invalidate?null:loadTime, !invalidate && useCache);
return CollectionTupleSource.createUpdateCountTupleSource(rowCount);
} else if (StringUtil.endsWithIgnoreCase(proc.getProcedureCallableName(), REFRESHMATVIEWROW)) {
Object groupID = validateMatView(metadata, proc);
@@ -408,9 +445,9 @@
if (load) {
if (!info.isValid()) {
//blocking load
- loadGlobalTable(context, group, tableName, globalStore, info, loadTime, true);
+ loadGlobalTable(context, group, tableName, null, globalStore, info, loadTime, true);
} else {
- loadAsynch(context, group, tableName, globalStore, info, loadTime);
+ loadAsynch(context, group, tableName, null, globalStore, info, loadTime);
}
}
table = globalStore.getOrCreateTempTable(tableName, query, bufferManager, false);
@@ -435,13 +472,13 @@
}
private void loadAsynch(final CommandContext context,
- final GroupSymbol group, final String tableName,
+ final GroupSymbol group, final String tableName,final String viewName,
final TempTableStore globalStore, final MatTableInfo info,
final Long loadTime) {
Callable<Integer> toCall = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
- return loadGlobalTable(context, group, tableName, globalStore, info, loadTime, true);
+ return loadGlobalTable(context, group, tableName, viewName, globalStore, info, loadTime, true);
}
};
FutureTask<Integer> task = new FutureTask<Integer>(toCall);
@@ -449,9 +486,9 @@
}
private int loadGlobalTable(CommandContext context,
- GroupSymbol group, final String tableName,
+ GroupSymbol group, final String tableName, final String viewName,
TempTableStore globalStore, MatTableInfo info, Long loadTime, boolean useCache)
- throws TeiidComponentException, TeiidProcessingException {
+ throws TeiidComponentException, TeiidProcessingException {
LogManager.logInfo(LogConstants.CTX_MATVIEWS, QueryPlugin.Util.getString("TempTableDataManager.loading", tableName)); //$NON-NLS-1$
QueryMetadataInterface metadata = context.getMetadata();
Create create = new Create();
@@ -477,9 +514,11 @@
}
}
int rowCount = -1;
+ boolean tableUpdated = false;
+ String fullName = null;
try {
- String fullName = metadata.getFullName(group.getMetadataID());
- TupleSource ts = null;
+ fullName = metadata.getFullName(group.getMetadataID());
+ TupleSource ts = null;
CacheID cid = null;
if (distributedCache != null) {
cid = new CacheID(new ParseInfo(), fullName, context.getVdbName(),
@@ -487,6 +526,7 @@
if (useCache) {
CachedResults cr = this.distributedCache.get(cid);
if (cr != null) {
+ LogManager.logInfo(LogConstants.CTX_MATVIEWS, QueryPlugin.Util.getString("TempTableDataManager.cache_load", tableName)); //$NON-NLS-1$
ts = cr.getResults().createIndexedTupleSource();
}
}
@@ -501,14 +541,15 @@
String transformation = metadata.getVirtualPlan(group.getMetadataID()).getQuery();
QueryProcessor qp = context.getQueryProcessorFactory().createQueryProcessor(transformation, fullName, context);
qp.setNonBlocking(true);
-
+
if (distributedCache != null) {
CachedResults cr = new CachedResults();
BatchCollector bc = qp.createBatchCollector();
TupleBuffer tb = bc.collectTuples();
cr.setResults(tb);
- touchTable(context, fullName, true);
- this.distributedCache.put(cid, FunctionMethod.VDB_DETERMINISTIC, cr, info.getTtl());
+ touchTable(context, fullName, viewName, true, info.getUpdateTime());
+ this.distributedCache.put(cid, FunctionMethod.VDB_DETERMINISTIC, cr, info.getTtl());
+ tableUpdated = true;
ts = tb.createIndexedTupleSource();
} else {
ts = new BatchCollector.BatchProducerTupleSource(qp);
@@ -541,19 +582,40 @@
globalStore.swapTempTable(tableName, table);
info.setState(MatState.LOADED, true, loadTime);
LogManager.logInfo(LogConstants.CTX_MATVIEWS, QueryPlugin.Util.getString("TempTableDataManager.loaded", tableName, rowCount)); //$NON-NLS-1$
+ if (tableUpdated) {
+ initiateRefreshAcrossCluster(context, fullName, viewName);
+ }
}
}
return rowCount;
}
- private void touchTable(CommandContext context, String fullName, boolean valid) {
+ private void touchTable(CommandContext context, String fullName, String viewName, boolean valid, long loadtime) {
MatTableKey key = new MatTableKey();
key.name = fullName;
key.vdb = new VDBKey(context.getVdbName(), context.getVdbVersion());
MatTableEntry matTableEntry = new MatTableEntry();
matTableEntry.valid = valid;
+ matTableEntry.viewName = viewName;
+ matTableEntry.lastUpdate = loadtime;
tables.put(key, matTableEntry, null);
}
+
+ private void initiateRefreshAcrossCluster(CommandContext context, String fullName, String viewName) {
+ MatTableKey key = new MatTableKey();
+ key.name = fullName;
+ key.vdb = new VDBKey(context.getVdbName(), context.getVdbVersion());
+ MatTableEntry matTableEntry = new MatTableEntry();
+ matTableEntry.valid = true;
+ matTableEntry.viewName = viewName;
+ matTableEntry.lastUpdate = System.currentTimeMillis();
+ MatTableEntry entry = refreshJob.put(key, matTableEntry, null);
+ if (entry == null) {
+ // in the case of refreshjob, cacheCreate are not being notified correctly due to nature of how Teiid uses the cache
+ // so, in order to get a cacheModified event insert again.
+ refreshJob.put(key, matTableEntry, null);
+ }
+ }
/**
* Return a list of ElementSymbols for the given index/key object
Modified: branches/7.1.1.CP3/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- branches/7.1.1.CP3/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-25 15:46:41 UTC (rev 3332)
@@ -783,6 +783,7 @@
TempTableDataManager.failed_load=Failed to load materialized view table {0}.
TempTableDataManager.loaded=Loaded materialized view table {0} with row count {1}.
+TempTableDataManager.cache_load=Loaded materialized view table {0} from cached contents from another clustered node.
TempTableDataManager.loading=Loading materialized view table {0}
TempTableDataManager.not_implicit_matview={0} does not target an internal materialized view.
TempTableDataManager.row_refresh_pk=Materialized view {0} cannot have a row refreshed since there is no primary key.
Modified: branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java
===================================================================
--- branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -74,7 +74,7 @@
command.run();
}
};
- dataManager = new TempTableDataManager(hdm, bm, executor, cache, cache, new DefaultCacheFactory());
+ dataManager = new TempTableDataManager(hdm, bm, executor, cache, cache, new DefaultCacheFactory(), null);
}
private void execute(String sql, List<?>... expectedResults) throws Exception {
Modified: branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -245,7 +245,7 @@
command.run();
}
};
- dataManager = new TempTableDataManager(dataManager, bufferMgr, executor, cache, null, null);
+ dataManager = new TempTableDataManager(dataManager, bufferMgr, executor, cache, null, null, null);
}
if (context.getQueryProcessorFactory() == null) {
context.setQueryProcessorFactory(new QueryProcessorFactoryImpl(bufferMgr, dataManager, new DefaultCapabilitiesFinder(), null, context.getMetadata()));
Modified: branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -76,7 +76,7 @@
command.run();
}
};
- dataManager = new TempTableDataManager(fdm, bm, executor, cache, null, null);
+ dataManager = new TempTableDataManager(fdm, bm, executor, cache, null, null, null);
}
@Test public void testInsertWithQueryExpression() throws Exception {
Modified: branches/7.1.1.CP3/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
===================================================================
--- branches/7.1.1.CP3/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-07-25 15:46:41 UTC (rev 3332)
@@ -70,6 +70,7 @@
import org.teiid.adminapi.impl.WorkerPoolStatisticsMetadata;
import org.teiid.adminapi.jboss.AdminProvider;
import org.teiid.cache.CacheFactory;
+import org.teiid.cache.CacheListener;
import org.teiid.client.DQP;
import org.teiid.client.RequestMessage;
import org.teiid.client.ResultsMessage;
@@ -97,6 +98,9 @@
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
import org.teiid.net.TeiidURL;
+import org.teiid.query.tempdata.TempTableDataManager;
+import org.teiid.query.tempdata.TempTableDataManager.MatTableEntry;
+import org.teiid.query.tempdata.TempTableDataManager.MatTableKey;
import org.teiid.security.SecurityHelper;
import org.teiid.transport.ClientServiceRegistry;
import org.teiid.transport.ClientServiceRegistryImpl;
@@ -147,7 +151,8 @@
public void start() {
dqpCore.setTransactionService((TransactionService)LogManager.createLoggingProxy(LogConstants.CTX_TXN_LOG, transactionServerImpl, new Class[] {TransactionService.class}, MessageLevel.DETAIL));
-
+ dqpCore.setMatTableListener(getMatTableListener());
+
// create the necessary services
createClientServices();
@@ -497,7 +502,7 @@
@Override
@ManagementOperation(description="Execute a sql query", params={@ManagementParameter(name="vdbName"),@ManagementParameter(name="vdbVersion"), @ManagementParameter(name="command"), @ManagementParameter(name="timoutInMilli")})
- public List<List> executeQuery(final String vdbName, final int version, final String command, final long timoutInMilli) throws AdminException {
+ public List<List> executeQuery(final String vdbName, final int version, final String command, final long timoutInMilli) throws AdminException {
Properties properties = new Properties();
properties.setProperty(TeiidURL.JDBC.VDB_NAME, vdbName);
properties.setProperty(TeiidURL.JDBC.VDB_VERSION, String.valueOf(version));
@@ -530,7 +535,14 @@
request.setExecutionId(0L);
request.setRowLimit(getMaxRowsFetchSize()); // this would limit the number of rows that are returned.
Future<ResultsMessage> message = dqpCore.executeRequest(requestID, request);
- ResultsMessage rm = message.get(timoutInMilli, TimeUnit.MILLISECONDS);
+
+ ResultsMessage rm = null;
+ if (timoutInMilli < 0) {
+ rm = message.get();
+ }
+ else {
+ rm = message.get(timoutInMilli, TimeUnit.MILLISECONDS);
+ }
if (rm.getException() != null) {
throw new AdminProcessingException(rm.getException());
@@ -607,4 +619,39 @@
}
return newResults;
}
+
+ private CacheListener<TempTableDataManager.MatTableKey, TempTableDataManager.MatTableEntry> getMatTableListener() {
+ return new CacheListener<TempTableDataManager.MatTableKey, TempTableDataManager.MatTableEntry>() {
+
+ @Override
+ public void cacheChanged() {
+ }
+
+ @Override
+ public void cacheCreated(MatTableKey key, MatTableEntry value) {
+ refreshMatView(key, value);
+ }
+
+ @Override
+ public void cacheModified(MatTableKey key, MatTableEntry value) {
+ refreshMatView(key, value);
+ }
+
+ private void refreshMatView(MatTableKey key, MatTableEntry value) {
+ if (value != null) {
+ try {
+ if (value.allowsUpdate()) {
+ executeQuery(key.getVDBName(), key.getVDBVersion(), "execute SYSADMIN.refreshmatview(viewname=>'"+value.getViewName()+"',invalidate=>false)", -1); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } catch (AdminException e) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, e, IntegrationPlugin.Util.getString("error_refresh", value.getViewName() )); //$NON-NLS-1$
+ }
+ }
+ }
+ @Override
+ public void cacheRemoved(MatTableKey key, MatTableEntry value) {
+
+ }
+ };
+ }
}
Modified: branches/7.1.1.CP3/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
===================================================================
--- branches/7.1.1.CP3/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties 2011-07-23 11:41:47 UTC (rev 3331)
+++ branches/7.1.1.CP3/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties 2011-07-25 15:46:41 UTC (rev 3332)
@@ -46,3 +46,4 @@
distribute_failed=Deploy of the archive failed {0}
template_not_found=Template not found for {0}
admin_executing=JOPR admin {0} is executing command {1}
+error_refresh=error occurred during refreshing the materialized view entries for view {0}
\ No newline at end of file
13 years, 5 months
teiid SVN: r3331 - in trunk: api/src/main/java/org/teiid/language/visitor and 10 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-23 07:41:47 -0400 (Sat, 23 Jul 2011)
New Revision: 3331
Added:
trunk/api/src/main/java/org/teiid/language/WindowSpecification.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowSpecification.java
Removed:
trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
Modified:
trunk/api/src/main/java/org/teiid/language/WindowFunction.java
trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
Log:
TEIID-1667 correcting unit tests and separating out a windowspecification class
Modified: trunk/api/src/main/java/org/teiid/language/WindowFunction.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/WindowFunction.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/api/src/main/java/org/teiid/language/WindowFunction.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -22,8 +22,6 @@
package org.teiid.language;
-import java.util.List;
-
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
import org.teiid.language.visitor.LanguageObjectVisitor;
@@ -31,8 +29,7 @@
public class WindowFunction extends BaseLanguageObject implements Expression {
private AggregateFunction function;
- private List<Expression> partition;
- private OrderBy orderBy;
+ private WindowSpecification windowSpecification;
public WindowFunction() {
@@ -46,21 +43,13 @@
this.function = expression;
}
- public List<Expression> getPartition() {
- return partition;
+ public WindowSpecification getWindowSpecification() {
+ return windowSpecification;
}
- public void setPartition(List<Expression> grouping) {
- this.partition = grouping;
+ public void setWindowSpecification(WindowSpecification windowSpecification) {
+ this.windowSpecification = windowSpecification;
}
-
- public OrderBy getOrderBy() {
- return orderBy;
- }
-
- public void setOrderBy(OrderBy orderBy) {
- this.orderBy = orderBy;
- }
@Override
public Class<?> getType() {
@@ -74,7 +63,7 @@
@Override
public int hashCode() {
- return HashCodeUtil.hashCode(function.hashCode(), partition, orderBy);
+ return HashCodeUtil.hashCode(function.hashCode(), windowSpecification);
}
public boolean equals(Object obj) {
@@ -86,8 +75,7 @@
}
WindowFunction other = (WindowFunction)obj;
return EquivalenceUtil.areEqual(this.function, other.function) &&
- EquivalenceUtil.areEqual(this.partition, other.partition) &&
- EquivalenceUtil.areEqual(this.orderBy, other.orderBy);
+ EquivalenceUtil.areEqual(this.windowSpecification, other.windowSpecification);
}
}
Added: trunk/api/src/main/java/org/teiid/language/WindowSpecification.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/WindowSpecification.java (rev 0)
+++ trunk/api/src/main/java/org/teiid/language/WindowSpecification.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -0,0 +1,78 @@
+/*
+ * 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.language;
+
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.HashCodeUtil;
+import org.teiid.language.visitor.LanguageObjectVisitor;
+
+public class WindowSpecification extends BaseLanguageObject {
+
+ private List<Expression> partition;
+ private OrderBy orderBy;
+
+ public WindowSpecification() {
+
+ }
+
+ public List<Expression> getPartition() {
+ return partition;
+ }
+
+ public void setPartition(List<Expression> grouping) {
+ this.partition = grouping;
+ }
+
+ public OrderBy getOrderBy() {
+ return orderBy;
+ }
+
+ public void setOrderBy(OrderBy orderBy) {
+ this.orderBy = orderBy;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageObjectVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeUtil.hashCode(partition.hashCode(), orderBy);
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof WindowSpecification)) {
+ return false;
+ }
+ WindowSpecification other = (WindowSpecification)obj;
+ return EquivalenceUtil.areEqual(this.partition, other.partition) &&
+ EquivalenceUtil.areEqual(this.orderBy, other.orderBy);
+ }
+
+}
Property changes on: trunk/api/src/main/java/org/teiid/language/WindowSpecification.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -52,6 +52,7 @@
import org.teiid.language.SubqueryIn;
import org.teiid.language.Update;
import org.teiid.language.WindowFunction;
+import org.teiid.language.WindowSpecification;
import org.teiid.language.With;
import org.teiid.language.WithItem;
@@ -253,8 +254,13 @@
@Override
public void visit(WindowFunction windowFunction) {
visitNode(windowFunction.getFunction());
- visitNodes(windowFunction.getPartition());
- visitNode(windowFunction.getOrderBy());
+ visitNode(windowFunction.getWindowSpecification());
}
+ @Override
+ public void visit(WindowSpecification windowSpecification) {
+ visitNodes(windowSpecification.getPartition());
+ visitNode(windowSpecification.getOrderBy());
+ }
+
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -58,6 +58,7 @@
import org.teiid.language.SubqueryIn;
import org.teiid.language.Update;
import org.teiid.language.WindowFunction;
+import org.teiid.language.WindowSpecification;
import org.teiid.language.With;
import org.teiid.language.WithItem;
@@ -102,4 +103,5 @@
public void visit(With obj);
public void visit(WithItem obj);
public void visit(WindowFunction windowFunction);
+ public void visit(WindowSpecification windowSpecification);
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -73,6 +73,7 @@
import org.teiid.language.TableReference;
import org.teiid.language.Update;
import org.teiid.language.WindowFunction;
+import org.teiid.language.WindowSpecification;
import org.teiid.language.With;
import org.teiid.language.WithItem;
import org.teiid.language.Argument.Direction;
@@ -924,23 +925,28 @@
buffer.append(Tokens.SPACE);
buffer.append(OVER);
buffer.append(Tokens.SPACE);
+ append(windowFunction.getWindowSpecification());
+ }
+
+ @Override
+ public void visit(WindowSpecification windowSpecification) {
buffer.append(Tokens.LPAREN);
boolean needsSpace = false;
- if (windowFunction.getPartition() != null) {
+ if (windowSpecification.getPartition() != null) {
buffer.append(PARTITION);
buffer.append(Tokens.SPACE);
buffer.append(BY);
buffer.append(Tokens.SPACE);
- append(windowFunction.getPartition());
+ append(windowSpecification.getPartition());
needsSpace = true;
}
- if (windowFunction.getOrderBy() != null) {
+ if (windowSpecification.getOrderBy() != null) {
if (needsSpace) {
buffer.append(Tokens.SPACE);
}
- append(windowFunction.getOrderBy());
+ append(windowSpecification.getOrderBy());
}
- buffer.append(Tokens.RPAREN);
+ buffer.append(Tokens.RPAREN);
}
/**
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -63,6 +63,7 @@
import org.teiid.language.SubqueryComparison;
import org.teiid.language.SubqueryIn;
import org.teiid.language.TableReference;
+import org.teiid.language.WindowSpecification;
import org.teiid.language.With;
import org.teiid.language.WithItem;
import org.teiid.language.Argument.Direction;
@@ -461,7 +462,7 @@
Ordering direction = items.get(i).isAscending() ? Ordering.ASC: Ordering.DESC;
SortSpecification orderByItem = null;
- if(items.get(i).isUnrelated() || (!set && symbol instanceof ElementSymbol)){
+ if(!set && (items.get(i).isUnrelated() || symbol instanceof ElementSymbol)){
orderByItem = new SortSpecification(direction, translate(symbol));
} else {
orderByItem = new SortSpecification(direction, new ColumnReference(null, SingleElementSymbol.getShortName(symbol.getOutputName()), null, symbol.getType()));
@@ -497,14 +498,17 @@
org.teiid.language.WindowFunction translate(WindowFunction windowFunction) {
org.teiid.language.WindowFunction result = new org.teiid.language.WindowFunction();
result.setFunction(translate(windowFunction.getFunction()));
- result.setOrderBy(translate(windowFunction.getOrderBy(), false));
- if (windowFunction.getPartition() != null) {
- ArrayList<org.teiid.language.Expression> partition = new ArrayList<org.teiid.language.Expression>(windowFunction.getPartition().size());
- for (Expression ex : windowFunction.getPartition()) {
- partition.add(translate(ex));
+ WindowSpecification ws = new WindowSpecification();
+ ws.setOrderBy(translate(windowFunction.getWindowSpecification().getOrderBy(), false));
+ List<Expression> partition = windowFunction.getWindowSpecification().getPartition();
+ if (partition != null) {
+ ArrayList<org.teiid.language.Expression> partitionList = new ArrayList<org.teiid.language.Expression>(partition.size());
+ for (Expression ex : partition) {
+ partitionList.add(translate(ex));
}
- result.setPartition(partition);
+ ws.setPartition(partitionList);
}
+ result.setWindowSpecification(ws);
return result;
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -97,6 +97,7 @@
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.TextLine;
import org.teiid.query.sql.symbol.WindowFunction;
+import org.teiid.query.sql.symbol.WindowSpecification;
import org.teiid.query.sql.symbol.XMLAttributes;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
@@ -224,4 +225,5 @@
public void visit(AlterTrigger obj) {}
public void visit(WindowFunction windowFunction) {}
+ public void visit(WindowSpecification windowSpecification) {}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -79,7 +79,7 @@
* @return true if the expression does not appear in the select clause
*/
public boolean isUnrelated() {
- return expressionPosition == null || expressionPosition == -1;
+ return getExpressionPosition() == -1;
}
@Override
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -102,6 +102,7 @@
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.TextLine;
import org.teiid.query.sql.symbol.WindowFunction;
+import org.teiid.query.sql.symbol.WindowSpecification;
import org.teiid.query.sql.symbol.XMLAttributes;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
@@ -700,7 +701,14 @@
public void visit(WindowFunction obj) {
preVisitVisitor(obj);
visitNode(obj.getFunction());
- visitNodes(obj.getPartition());
+ visitNode(obj.getWindowSpecification());
+ postVisitVisitor(obj);
+ }
+
+ @Override
+ public void visit(WindowSpecification obj) {
+ preVisitVisitor(obj);
+ visitNodes(obj.getPartition());
visitNode(obj.getOrderBy());
postVisitVisitor(obj);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -22,20 +22,15 @@
package org.teiid.query.sql.symbol;
-import java.util.List;
-
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
-import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.visitor.SQLStringVisitor;
public class WindowFunction implements Expression {
private AggregateSymbol function;
- private List<Expression> partition;
- private OrderBy orderBy;
+ private WindowSpecification windowSpecification;
public WindowFunction() {
@@ -50,22 +45,14 @@
this.function.setWindowed(true);
}
- public List<Expression> getPartition() {
- return partition;
+ public WindowSpecification getWindowSpecification() {
+ return windowSpecification;
}
- public void setPartition(List<Expression> grouping) {
- this.partition = grouping;
+ public void setWindowSpecification(WindowSpecification windowSpecification) {
+ this.windowSpecification = windowSpecification;
}
- public OrderBy getOrderBy() {
- return orderBy;
- }
-
- public void setOrderBy(OrderBy orderBy) {
- this.orderBy = orderBy;
- }
-
@Override
public Class<?> getType() {
return function.getType();
@@ -83,7 +70,7 @@
@Override
public int hashCode() {
- return HashCodeUtil.hashCode(function.hashCode(), partition, orderBy);
+ return HashCodeUtil.hashCode(function.hashCode(), windowSpecification);
}
@Override
@@ -96,20 +83,14 @@
}
WindowFunction other = (WindowFunction)obj;
return EquivalenceUtil.areEqual(this.function, other.function) &&
- EquivalenceUtil.areEqual(this.partition, other.partition) &&
- EquivalenceUtil.areEqual(this.orderBy, other.orderBy);
+ EquivalenceUtil.areEqual(this.windowSpecification, other.windowSpecification);
}
@Override
public WindowFunction clone() {
WindowFunction clone = new WindowFunction();
clone.setFunction((AggregateSymbol) this.function.clone());
- if (this.partition != null) {
- clone.setPartition(LanguageObject.Util.deepClone(this.partition, Expression.class));
- }
- if (this.orderBy != null) {
- clone.setOrderBy(this.orderBy.clone());
- }
+ clone.setWindowSpecification(this.windowSpecification.clone());
return clone;
}
Added: trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowSpecification.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowSpecification.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowSpecification.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -0,0 +1,99 @@
+/*
+ * 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.query.sql.symbol;
+
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.HashCodeUtil;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.OrderBy;
+import org.teiid.query.sql.visitor.SQLStringVisitor;
+
+public class WindowSpecification implements LanguageObject {
+
+ private List<Expression> partition;
+ private OrderBy orderBy;
+
+ public WindowSpecification() {
+
+ }
+
+ public List<Expression> getPartition() {
+ return partition;
+ }
+
+ public void setPartition(List<Expression> grouping) {
+ this.partition = grouping;
+ }
+
+ public OrderBy getOrderBy() {
+ return orderBy;
+ }
+
+ public void setOrderBy(OrderBy orderBy) {
+ this.orderBy = orderBy;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeUtil.hashCode(0, partition, orderBy);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof WindowSpecification)) {
+ return false;
+ }
+ WindowSpecification other = (WindowSpecification)obj;
+ return EquivalenceUtil.areEqual(this.partition, other.partition) &&
+ EquivalenceUtil.areEqual(this.orderBy, other.orderBy);
+ }
+
+ @Override
+ public WindowSpecification clone() {
+ WindowSpecification clone = new WindowSpecification();
+ if (this.partition != null) {
+ clone.setPartition(LanguageObject.Util.deepClone(this.partition, Expression.class));
+ }
+ if (this.orderBy != null) {
+ clone.setOrderBy(this.orderBy.clone());
+ }
+ return clone;
+ }
+
+ @Override
+ public String toString() {
+ return SQLStringVisitor.getSQLString(this);
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowSpecification.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -67,7 +67,7 @@
import org.teiid.query.sql.symbol.QueryString;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.SingleElementSymbol;
-import org.teiid.query.sql.symbol.WindowFunction;
+import org.teiid.query.sql.symbol.WindowSpecification;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLSerialize;
@@ -450,11 +450,11 @@
}
@Override
- public void visit(WindowFunction windowFunction) {
- if (windowFunction.getPartition() == null) {
+ public void visit(WindowSpecification windowSpecification) {
+ if (windowSpecification.getPartition() == null) {
return;
}
- List<Expression> partition = windowFunction.getPartition();
+ List<Expression> partition = windowSpecification.getPartition();
for (int i = 0; i < partition.size(); i++) {
partition.set(i, replaceExpression(partition.get(i)));
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -126,6 +126,7 @@
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.symbol.TextLine;
import org.teiid.query.sql.symbol.WindowFunction;
+import org.teiid.query.sql.symbol.WindowSpecification;
import org.teiid.query.sql.symbol.XMLAttributes;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
@@ -2056,23 +2057,28 @@
append(SPACE);
append(OVER);
append(SPACE);
+ append(windowFunction.getWindowSpecification());
+ }
+
+ @Override
+ public void visit(WindowSpecification windowSpecification) {
append(Tokens.LPAREN);
boolean needsSpace = false;
- if (windowFunction.getPartition() != null) {
+ if (windowSpecification.getPartition() != null) {
append(PARTITION);
append(SPACE);
append(BY);
append(SPACE);
- registerNodes(windowFunction.getPartition(), 0);
+ registerNodes(windowSpecification.getPartition(), 0);
needsSpace = true;
}
- if (windowFunction.getOrderBy() != null) {
+ if (windowSpecification.getOrderBy() != null) {
if (needsSpace) {
append(SPACE);
}
- append(windowFunction.getOrderBy());
+ append(windowSpecification.getOrderBy());
}
- append(Tokens.RPAREN);
+ append(Tokens.RPAREN);
}
public static String escapeSinglePart( String part ) {
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -1211,7 +1211,7 @@
case RANK:
case DENSE_RANK:
case ROW_NUMBER:
- if (windowFunction.getOrderBy() == null) {
+ if (windowFunction.getWindowSpecification().getOrderBy() == null) {
handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.analytical_requires_order_by", windowFunction), windowFunction); //$NON-NLS-1$
}
}
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-07-23 11:41:47 UTC (rev 3331)
@@ -3456,9 +3456,11 @@
<RPAREN>
{
WindowFunction result = new WindowFunction();
+ WindowSpecification ws = new WindowSpecification();
result.setFunction((AggregateSymbol)agg);
- result.setPartition(partitionList);
- result.setOrderBy(orderBy);
+ ws.setPartition(partitionList);
+ ws.setOrderBy(orderBy);
+ result.setWindowSpecification(ws);
return result;
}
}
Deleted: trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -1,49 +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.query.optimizer;
-
-import static org.teiid.query.optimizer.TestOptimizer.*;
-
-import org.junit.Test;
-import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
-import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
-import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
-import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
-import org.teiid.query.processor.ProcessorPlan;
-import org.teiid.query.unittest.RealMetadataFactory;
-
-public class TestWindowFunctions {
-
- @Test public void testViewNotRemoved() throws Exception {
- BasicSourceCapabilities caps = getTypicalCapabilities();
- caps.setCapabilitySupport(Capability.ELEMENTARY_OLAP, true);
- caps.setCapabilitySupport(Capability.QUERY_FROM_INLINE_VIEWS, true);
- ProcessorPlan plan = TestOptimizer.helpPlan("SELECT y FROM (select row_number() over (order by e1) as y from pm1.g1) as x where x.y = 10", //$NON-NLS-1$
- RealMetadataFactory.example1Cached(), null, new DefaultCapabilitiesFinder(caps),
- new String[] {
- "SELECT v_0.c_0 FROM (SELECT ROW_NUMBER() OVER (ORDER BY g_0.e1) AS c_0 FROM pm1.g1 AS g_0) AS v_0 WHERE v_0.c_0 = 10"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
-
- checkNodeTypes(plan, FULL_PUSHDOWN);
- }
-
-}
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-07-22 21:13:20 UTC (rev 3330)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-07-23 11:41:47 UTC (rev 3331)
@@ -117,6 +117,7 @@
import org.teiid.query.sql.symbol.TestSearchedCaseExpression;
import org.teiid.query.sql.symbol.TextLine;
import org.teiid.query.sql.symbol.WindowFunction;
+import org.teiid.query.sql.symbol.WindowSpecification;
import org.teiid.query.sql.symbol.XMLAttributes;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
@@ -6850,8 +6851,10 @@
Query query = new Query();
WindowFunction wf = new WindowFunction();
wf.setFunction(new AggregateSymbol("expr", "ROW_NUMBER", false, null));
- wf.setPartition(new ArrayList<Expression>(Arrays.asList(new ElementSymbol("x"))));
- wf.setOrderBy(new OrderBy(Arrays.asList(new ElementSymbol("y"))));
+ WindowSpecification ws = new WindowSpecification();
+ ws.setPartition(new ArrayList<Expression>(Arrays.asList(new ElementSymbol("x"))));
+ ws.setOrderBy(new OrderBy(Arrays.asList(new ElementSymbol("y"))));
+ wf.setWindowSpecification(ws);
query.setSelect(new Select(Arrays.asList(new ExpressionSymbol("x", wf))));
query.setFrom(new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("g")))));
helpTest(sql, "SELECT ROW_NUMBER() OVER (PARTITION BY x ORDER BY y) FROM g", query);
13 years, 5 months
teiid SVN: r3330 - in trunk: api/src/main/java/org/teiid/language/visitor and 16 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-22 17:13:20 -0400 (Fri, 22 Jul 2011)
New Revision: 3330
Added:
trunk/api/src/main/java/org/teiid/language/WindowFunction.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
Modified:
trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.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/CapabilitiesUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.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/RulePushSelectCriteria.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java
trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
Log:
TEIID-1667 refining aggregate validation and adding pushdown support for window functions
Added: trunk/api/src/main/java/org/teiid/language/WindowFunction.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/WindowFunction.java (rev 0)
+++ trunk/api/src/main/java/org/teiid/language/WindowFunction.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -0,0 +1,93 @@
+/*
+ * 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.language;
+
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.HashCodeUtil;
+import org.teiid.language.visitor.LanguageObjectVisitor;
+
+public class WindowFunction extends BaseLanguageObject implements Expression {
+
+ private AggregateFunction function;
+ private List<Expression> partition;
+ private OrderBy orderBy;
+
+ public WindowFunction() {
+
+ }
+
+ public AggregateFunction getFunction() {
+ return function;
+ }
+
+ public void setFunction(AggregateFunction expression) {
+ this.function = expression;
+ }
+
+ public List<Expression> getPartition() {
+ return partition;
+ }
+
+ public void setPartition(List<Expression> grouping) {
+ this.partition = grouping;
+ }
+
+ public OrderBy getOrderBy() {
+ return orderBy;
+ }
+
+ public void setOrderBy(OrderBy orderBy) {
+ this.orderBy = orderBy;
+ }
+
+ @Override
+ public Class<?> getType() {
+ return function.getType();
+ }
+
+ @Override
+ public void acceptVisitor(LanguageObjectVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeUtil.hashCode(function.hashCode(), partition, orderBy);
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof WindowFunction)) {
+ return false;
+ }
+ WindowFunction other = (WindowFunction)obj;
+ return EquivalenceUtil.areEqual(this.function, other.function) &&
+ EquivalenceUtil.areEqual(this.partition, other.partition) &&
+ EquivalenceUtil.areEqual(this.orderBy, other.orderBy);
+ }
+
+}
Property changes on: trunk/api/src/main/java/org/teiid/language/WindowFunction.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -27,44 +27,9 @@
import java.util.HashSet;
import java.util.Set;
-import org.teiid.language.AggregateFunction;
-import org.teiid.language.AndOr;
-import org.teiid.language.Argument;
-import org.teiid.language.BatchedUpdates;
-import org.teiid.language.Call;
import org.teiid.language.ColumnReference;
-import org.teiid.language.Comparison;
-import org.teiid.language.Delete;
-import org.teiid.language.DerivedColumn;
-import org.teiid.language.DerivedTable;
-import org.teiid.language.Exists;
-import org.teiid.language.ExpressionValueSource;
-import org.teiid.language.Function;
-import org.teiid.language.GroupBy;
-import org.teiid.language.In;
-import org.teiid.language.Insert;
-import org.teiid.language.IsNull;
-import org.teiid.language.IteratorValueSource;
-import org.teiid.language.Join;
import org.teiid.language.LanguageObject;
-import org.teiid.language.Like;
-import org.teiid.language.Limit;
-import org.teiid.language.Literal;
import org.teiid.language.NamedTable;
-import org.teiid.language.Not;
-import org.teiid.language.OrderBy;
-import org.teiid.language.ScalarSubquery;
-import org.teiid.language.SearchedCase;
-import org.teiid.language.SearchedWhenClause;
-import org.teiid.language.Select;
-import org.teiid.language.SetClause;
-import org.teiid.language.SetQuery;
-import org.teiid.language.SortSpecification;
-import org.teiid.language.SubqueryComparison;
-import org.teiid.language.SubqueryIn;
-import org.teiid.language.Update;
-import org.teiid.language.With;
-import org.teiid.language.WithItem;
/**
@@ -72,7 +37,7 @@
* tree. Each visit method does an instanceof method to check whether the object
* is of the expected type.
*/
-public class CollectorVisitor<T> implements LanguageObjectVisitor {
+public class CollectorVisitor<T> extends HierarchyVisitor {
private Class<T> type;
private Collection<T> objects = new ArrayList<T>();
@@ -80,171 +45,20 @@
public CollectorVisitor(Class<T> type) {
this.type = type;
}
-
+
@SuppressWarnings("unchecked")
- private void checkInstance(LanguageObject obj) {
+ @Override
+ public void visitNode(LanguageObject obj) {
if(type.isInstance(obj)) {
this.objects.add((T)obj);
}
+ super.visitNode(obj);
}
-
+
public Collection<T> getCollectedObjects() {
return this.objects;
}
- public void visit(AggregateFunction obj) {
- checkInstance(obj);
- }
-
- public void visit(BatchedUpdates obj) {
- checkInstance(obj);
- }
-
- public void visit(Comparison obj) {
- checkInstance(obj);
- }
-
- public void visit(AndOr obj) {
- checkInstance(obj);
- }
-
- public void visit(Delete obj) {
- checkInstance(obj);
- }
-
- public void visit(ColumnReference obj) {
- checkInstance(obj);
- }
-
- public void visit(Exists obj) {
- checkInstance(obj);
- }
-
- public void visit(Function obj) {
- checkInstance(obj);
- }
-
- public void visit(NamedTable obj) {
- checkInstance(obj);
- }
-
- public void visit(GroupBy obj) {
- checkInstance(obj);
- }
-
- public void visit(In obj) {
- checkInstance(obj);
- }
-
- public void visit(DerivedTable obj) {
- checkInstance(obj);
- }
-
- public void visit(Insert obj) {
- checkInstance(obj);
- }
-
- public void visit(ExpressionValueSource obj) {
- checkInstance(obj);
- }
-
- public void visit(IsNull obj) {
- checkInstance(obj);
- }
-
- public void visit(Join obj) {
- checkInstance(obj);
- }
-
- public void visit(Like obj) {
- checkInstance(obj);
- }
-
- public void visit(Limit obj) {
- checkInstance(obj);
- }
-
- public void visit(Literal obj) {
- checkInstance(obj);
- }
-
- public void visit(Not obj) {
- checkInstance(obj);
- }
-
- public void visit(OrderBy obj) {
- checkInstance(obj);
- }
-
- public void visit(SortSpecification obj) {
- checkInstance(obj);
- }
-
- public void visit(Argument obj) {
- checkInstance(obj);
- }
-
- public void visit(Call obj) {
- checkInstance(obj);
- }
-
- public void visit(Select obj) {
- checkInstance(obj);
- }
-
- public void visit(ScalarSubquery obj) {
- checkInstance(obj);
- }
-
- public void visit(SearchedCase obj) {
- checkInstance(obj);
- }
-
- public void visit(DerivedColumn obj) {
- checkInstance(obj);
- }
-
- public void visit(SubqueryComparison obj) {
- checkInstance(obj);
- }
-
- public void visit(SubqueryIn obj) {
- checkInstance(obj);
- }
-
- public void visit(Update obj) {
- checkInstance(obj);
- }
-
- public void visit(SetQuery obj) {
- checkInstance(obj);
- }
-
- @Override
- public void visit(SetClause obj) {
- checkInstance(obj);
- }
-
- @Override
- public void visit(SearchedWhenClause obj) {
- checkInstance(obj);
- }
-
- @Override
- public void visit(IteratorValueSource obj) {
- checkInstance(obj);
- }
-
- @Override
- public void visit(With obj) {
- checkInstance(obj);
- }
-
- @Override
- public void visit(WithItem obj) {
- checkInstance(obj);
- }
-
/**
* This is a utility method to instantiate and run the visitor in conjunction
* with a HierarchyVisitor to collect all objects of the specified type
@@ -255,8 +69,7 @@
*/
public static <T> Collection<T> collectObjects(Class<T> type, LanguageObject object) {
CollectorVisitor<T> visitor = new CollectorVisitor<T>(type);
- DelegatingHierarchyVisitor hierarchyVisitor = new DelegatingHierarchyVisitor(visitor, null);
- hierarchyVisitor.visitNode(object);
+ visitor.visitNode(object);
return visitor.getCollectedObjects();
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -51,6 +51,7 @@
import org.teiid.language.SubqueryComparison;
import org.teiid.language.SubqueryIn;
import org.teiid.language.Update;
+import org.teiid.language.WindowFunction;
import org.teiid.language.With;
import org.teiid.language.WithItem;
@@ -249,5 +250,11 @@
}
}
-
+ @Override
+ public void visit(WindowFunction windowFunction) {
+ visitNode(windowFunction.getFunction());
+ visitNodes(windowFunction.getPartition());
+ visitNode(windowFunction.getOrderBy());
+ }
+
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -22,7 +22,44 @@
package org.teiid.language.visitor;
-import org.teiid.language.*;
+import org.teiid.language.AggregateFunction;
+import org.teiid.language.AndOr;
+import org.teiid.language.Argument;
+import org.teiid.language.BatchedUpdates;
+import org.teiid.language.Call;
+import org.teiid.language.ColumnReference;
+import org.teiid.language.Comparison;
+import org.teiid.language.Delete;
+import org.teiid.language.DerivedColumn;
+import org.teiid.language.DerivedTable;
+import org.teiid.language.Exists;
+import org.teiid.language.ExpressionValueSource;
+import org.teiid.language.Function;
+import org.teiid.language.GroupBy;
+import org.teiid.language.In;
+import org.teiid.language.Insert;
+import org.teiid.language.IsNull;
+import org.teiid.language.IteratorValueSource;
+import org.teiid.language.Join;
+import org.teiid.language.Like;
+import org.teiid.language.Limit;
+import org.teiid.language.Literal;
+import org.teiid.language.NamedTable;
+import org.teiid.language.Not;
+import org.teiid.language.OrderBy;
+import org.teiid.language.ScalarSubquery;
+import org.teiid.language.SearchedCase;
+import org.teiid.language.SearchedWhenClause;
+import org.teiid.language.Select;
+import org.teiid.language.SetClause;
+import org.teiid.language.SetQuery;
+import org.teiid.language.SortSpecification;
+import org.teiid.language.SubqueryComparison;
+import org.teiid.language.SubqueryIn;
+import org.teiid.language.Update;
+import org.teiid.language.WindowFunction;
+import org.teiid.language.With;
+import org.teiid.language.WithItem;
/**
*/
@@ -64,4 +101,5 @@
public void visit(IteratorValueSource obj);
public void visit(With obj);
public void visit(WithItem obj);
+ public void visit(WindowFunction windowFunction);
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -72,6 +72,7 @@
import org.teiid.language.SubqueryIn;
import org.teiid.language.TableReference;
import org.teiid.language.Update;
+import org.teiid.language.WindowFunction;
import org.teiid.language.With;
import org.teiid.language.WithItem;
import org.teiid.language.Argument.Direction;
@@ -916,6 +917,31 @@
append(obj.getSubquery());
buffer.append(Tokens.RPAREN);
}
+
+ @Override
+ public void visit(WindowFunction windowFunction) {
+ append(windowFunction.getFunction());
+ buffer.append(Tokens.SPACE);
+ buffer.append(OVER);
+ buffer.append(Tokens.SPACE);
+ buffer.append(Tokens.LPAREN);
+ boolean needsSpace = false;
+ if (windowFunction.getPartition() != null) {
+ buffer.append(PARTITION);
+ buffer.append(Tokens.SPACE);
+ buffer.append(BY);
+ buffer.append(Tokens.SPACE);
+ append(windowFunction.getPartition());
+ needsSpace = true;
+ }
+ if (windowFunction.getOrderBy() != null) {
+ if (needsSpace) {
+ buffer.append(Tokens.SPACE);
+ }
+ append(windowFunction.getOrderBy());
+ }
+ buffer.append(Tokens.RPAREN);
+ }
/**
* Gets the SQL string representation for a given ILanguageObject.
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -860,7 +860,7 @@
}
/**
- * @return true if Advanced OLAP operations are supporting
+ * @return true if Advanced OLAP operations are supported
* including the aggregate function filter clause.
* @since 7.5
*/
@@ -869,8 +869,9 @@
}
/**
- * @return true if Elementary OLAP operations are supporting
- * including window functions
+ * @return true if Elementary OLAP operations are supported
+ * including window functions and inline window specifications that include
+ * simple expressions in partitioning and ordering
* @since 7.5
*/
public boolean supportsElementaryOlapOperations() {
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -487,4 +487,14 @@
return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
}
+ @Override
+ public boolean supportsArrayAgg() {
+ return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
+ }
+
+ @Override
+ public boolean supportsElementaryOlapOperations() {
+ return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -117,6 +117,7 @@
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
import org.teiid.translator.TranslatorException;
@@ -487,9 +488,25 @@
return translate((SingleElementSymbol)expr);
} else if (expr instanceof Criteria) {
return translate((Criteria)expr);
+ } else if (expr instanceof WindowFunction) {
+ return translate((WindowFunction)expr);
}
throw new AssertionError();
}
+
+ org.teiid.language.WindowFunction translate(WindowFunction windowFunction) {
+ org.teiid.language.WindowFunction result = new org.teiid.language.WindowFunction();
+ result.setFunction(translate(windowFunction.getFunction()));
+ result.setOrderBy(translate(windowFunction.getOrderBy(), false));
+ if (windowFunction.getPartition() != null) {
+ ArrayList<org.teiid.language.Expression> partition = new ArrayList<org.teiid.language.Expression>(windowFunction.getPartition().size());
+ for (Expression ex : windowFunction.getPartition()) {
+ partition.add(translate(ex));
+ }
+ result.setPartition(partition);
+ }
+ return result;
+ }
Literal translate(Constant constant) {
Literal result = new Literal(constant.getValue(), constant.getType());
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 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -28,6 +28,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -112,16 +113,17 @@
import org.teiid.query.sql.proc.TriggerAction;
import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.AliasSymbol;
-import org.teiid.query.sql.symbol.MultipleElementSymbol;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.ExpressionSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.MultipleElementSymbol;
import org.teiid.query.sql.symbol.Reference;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
import org.teiid.query.sql.visitor.CorrelatedReferenceCollectorVisitor;
@@ -723,6 +725,8 @@
PlanNode plan = null;
+ LinkedHashSet<WindowFunction> windowFunctions = new LinkedHashSet<WindowFunction>();
+
if(query.getFrom() != null){
FromClause fromClause = mergeClauseTrees(query.getFrom());
@@ -741,7 +745,8 @@
}
// Attach grouping node on top
- Collection<AggregateSymbol> aggs = AggregateSymbolCollectorVisitor.getAggregates(query.getSelect(), true);
+ LinkedHashSet<AggregateSymbol> aggs = new LinkedHashSet<AggregateSymbol>();
+ AggregateSymbolCollectorVisitor.getAggregates(query.getSelect(), aggs, null, null, windowFunctions, null);
boolean hasGrouping = !aggs.isEmpty();
if (query.getHaving() != null) {
aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(query.getHaving(), true));
@@ -764,6 +769,12 @@
// Attach project on top
plan = attachProject(plan, query.getSelect());
+ if (query.getOrderBy() != null) {
+ AggregateSymbolCollectorVisitor.getAggregates(query.getOrderBy(), null, null, null, windowFunctions, null);
+ }
+ if (!windowFunctions.isEmpty()) {
+ plan.setProperty(Info.HAS_WINDOW_FUNCTIONS, true);
+ }
// Attach dup removal on top
if(query.getSelect().isDistinct()) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -98,6 +98,7 @@
// Project node properties
PROJECT_COLS, // List <SingleElementSymbol>
INTO_GROUP, // GroupSymbol
+ HAS_WINDOW_FUNCTIONS, // Boolean
// Select node properties
SELECT_CRITERIA, // Criteria
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -185,6 +185,13 @@
return false;
}
break;
+ case RANK:
+ case DENSE_RANK:
+ case ROW_NUMBER:
+ if (!caps.supportsCapability(Capability.ELEMENTARY_OLAP)) {
+ return false;
+ }
+ break;
default:
if (aggregate.isEnhancedNumeric()) {
if (!caps.supportsCapability(Capability.QUERY_AGGREGATES_ENHANCED_NUMERIC)) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -60,13 +60,12 @@
import org.teiid.query.sql.navigator.PostOrderNavigator;
import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.CaseExpression;
-import org.teiid.query.sql.symbol.Constant;
-import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.Function;
import org.teiid.query.sql.symbol.QueryString;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.TextLine;
+import org.teiid.query.sql.symbol.WindowFunction;
import org.teiid.query.sql.symbol.XMLAttributes;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
@@ -165,6 +164,13 @@
}
}
+ @Override
+ public void visit(WindowFunction windowFunction) {
+ if(! this.caps.supportsCapability(Capability.ELEMENTARY_OLAP)) {
+ markInvalid(windowFunction, "Window function not supported by source"); //$NON-NLS-1$
+ }
+ }
+
public void visit(CaseExpression obj) {
if(! this.caps.supportsCapability(Capability.QUERY_CASE)) {
markInvalid(obj, "CaseExpression pushdown not supported by source"); //$NON-NLS-1$
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 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -319,6 +319,10 @@
GroupSymbol virtualGroup,
PlanNode parentJoin,
QueryMetadataInterface metadata) {
+ if (projectNode.hasBooleanProperty(Info.HAS_WINDOW_FUNCTIONS)) {
+ return false;
+ }
+
List<SingleElementSymbol> selectSymbols = (List<SingleElementSymbol>)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS);
HashSet<GroupSymbol> groups = new HashSet<GroupSymbol>();
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -52,7 +52,9 @@
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
import org.teiid.query.sql.util.SymbolMap;
+import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.util.CommandContext;
@@ -560,17 +562,21 @@
if(projectNode.getChildCount() == 0) {
return false;
}
+ List<WindowFunction> windowFunctions = null;
+ if (projectNode.hasBooleanProperty(Info.HAS_WINDOW_FUNCTIONS)) {
+ windowFunctions = new LinkedList<WindowFunction>();
+ }
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
- Boolean conversionResult = checkConversion(symbolMap, ElementCollectorVisitor.getElements(crit, true));
+ Boolean conversionResult = checkConversion(symbolMap, ElementCollectorVisitor.getElements(crit, true), windowFunctions);
if (conversionResult == Boolean.FALSE) {
return false; //not convertable
}
if (!critNode.getSubqueryContainers().isEmpty()
- && checkConversion(symbolMap, critNode.getCorrelatedReferenceElements()) != null) {
+ && checkConversion(symbolMap, critNode.getCorrelatedReferenceElements(), windowFunctions) != null) {
return false; //not convertable, or has an aggregate for a correlated reference
}
@@ -591,7 +597,7 @@
}
private Boolean checkConversion(SymbolMap symbolMap,
- Collection<ElementSymbol> elements) {
+ Collection<ElementSymbol> elements, List<WindowFunction> windowFunctions) {
Boolean result = null;
for (ElementSymbol element : elements) {
@@ -609,6 +615,13 @@
if (!ElementCollectorVisitor.getAggregates(converted, false).isEmpty()) {
result = Boolean.TRUE;
}
+
+ if (windowFunctions != null) {
+ AggregateSymbolCollectorVisitor.getAggregates(converted, null, null, null, windowFunctions, null);
+ if (!windowFunctions.isEmpty()) {
+ return false;
+ }
+ }
}
return result;
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -2250,7 +2250,8 @@
expression.setAggregateFunction(Type.MAX);
}
}
- if (rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
+ if ((expression.getAggregateFunction() == Type.MAX || expression.getAggregateFunction() == Type.MIN)
+ && rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
return expression.getExpression();
}
if (expression.getExpression() != null && expression.getCondition() != null && !expression.respectsNulls()) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -79,7 +79,7 @@
* @return true if the expression does not appear in the select clause
*/
public boolean isUnrelated() {
- return expressionPosition != null && expressionPosition == -1;
+ return expressionPosition == null || expressionPosition == -1;
}
@Override
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -260,17 +260,14 @@
return false;
}
switch (getAggregateFunction()) {
- case COUNT:
- case AVG:
- case STDDEV_POP:
- case STDDEV_SAMP:
- case VAR_POP:
- case VAR_SAMP:
- case SUM:
- case ARRAY_AGG:
- return true;
+ case MAX:
+ case MIN:
+ case ANY:
+ case SOME:
+ case EVERY:
+ return false;
}
- return false;
+ return true;
}
public Expression getCondition() {
@@ -291,13 +288,17 @@
}
public boolean respectsNulls() {
- return this.aggregate == Type.ARRAY_AGG;
+ switch (this.aggregate) {
+ case TEXTAGG:
+ case ARRAY_AGG:
+ return true;
+ }
+ return false;
}
public boolean canStage() {
switch (this.aggregate) {
case TEXTAGG:
- return false;
case ARRAY_AGG:
return false;
case XMLAGG:
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -25,7 +25,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
@@ -99,7 +99,7 @@
Collection<? super AggregateSymbol> aggregates,
Collection<? super ElementSymbol> otherElements,
Collection<? super Expression> groupingColsUsed,
- Collection<? super Expression> windowFunctions,
+ Collection<? super WindowFunction> windowFunctions,
Collection<? extends Expression> groupingCols) {
AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(aggregates, otherElements);
visitor.windowFunctions = windowFunctions;
@@ -113,7 +113,7 @@
}
Collection<AggregateSymbol> aggregates = null;
if (removeDuplicates) {
- aggregates = new HashSet<AggregateSymbol>();
+ aggregates = new LinkedHashSet<AggregateSymbol>();
} else {
aggregates = new ArrayList<AggregateSymbol>();
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -67,6 +67,7 @@
import org.teiid.query.sql.symbol.QueryString;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLSerialize;
@@ -448,4 +449,15 @@
}
}
+ @Override
+ public void visit(WindowFunction windowFunction) {
+ if (windowFunction.getPartition() == null) {
+ return;
+ }
+ List<Expression> partition = windowFunction.getPartition();
+ for (int i = 0; i < partition.size(); i++) {
+ partition.set(i, replaceExpression(partition.get(i)));
+ }
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -165,6 +165,8 @@
// State during validation
private boolean isXML = false; // only used for Query commands
+ private boolean inQuery;
+
// update procedure being validated
private CreateUpdateProcedureCommand updateProc;
@@ -265,6 +267,7 @@
this.isXML = true;
validateXMLQuery(obj);
} else {
+ this.inQuery = true;
validateAggregates(obj);
//if it is select with no from, should not have ScalarSubQuery
@@ -1217,6 +1220,10 @@
@Override
public void visit(AggregateSymbol obj) {
+ if (!inQuery) {
+ handleValidationError(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level", obj), obj); //$NON-NLS-1$
+ return;
+ }
if (obj.getCondition() != null) {
Expression condition = obj.getCondition();
validateNoSubqueriesOrOuterReferences(condition);
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-22 21:13:20 UTC (rev 3330)
@@ -259,7 +259,7 @@
SQLParser.Unknown_join_type=Unknown join type: {0}
-SQLParser.Aggregate_only_top_level=Aggregate and window functions are not allowed in the FROM/WHERE/GROUP BY clauses: {0}
+SQLParser.Aggregate_only_top_level=Aggregate functions are only allowed HAVING/SELECT/ORDER BY clauses. Window functions are only allowed in the SELECT/ORDER BY clauses: {0}
SQLParser.window_only_top_level=Window functions are not allowed in the HAVING clause: {0}
SQLParser.Unknown_agg_func=Unknown aggregate function: {0}
SQLParser.Invalid_func=Invalid function name: [{0}]
Added: trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.optimizer;
+
+import static org.teiid.query.optimizer.TestOptimizer.*;
+
+import org.junit.Test;
+import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
+import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
+import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+public class TestWindowFunctions {
+
+ @Test public void testViewNotRemoved() throws Exception {
+ BasicSourceCapabilities caps = getTypicalCapabilities();
+ caps.setCapabilitySupport(Capability.ELEMENTARY_OLAP, true);
+ caps.setCapabilitySupport(Capability.QUERY_FROM_INLINE_VIEWS, true);
+ ProcessorPlan plan = TestOptimizer.helpPlan("SELECT y FROM (select row_number() over (order by e1) as y from pm1.g1) as x where x.y = 10", //$NON-NLS-1$
+ RealMetadataFactory.example1Cached(), null, new DefaultCapabilitiesFinder(caps),
+ new String[] {
+ "SELECT v_0.c_0 FROM (SELECT ROW_NUMBER() OVER (ORDER BY g_0.e1) AS c_0 FROM pm1.g1 AS g_0) AS v_0 WHERE v_0.c_0 = 10"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+
+ checkNodeTypes(plan, FULL_PUSHDOWN);
+ }
+
+}
Property changes on: trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -1709,6 +1709,9 @@
helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then null else null end IS NULL", TRUE_STR); //$NON-NLS-1$
}
+ @Test public void testRewriteConstantAgg2() throws Exception {
+ helpTestRewriteCommand("select count(2) from pm1.g1 group by e1", "SELECT COUNT(2) FROM pm1.g1 GROUP BY e1");
+ }
@Test public void testRewriteCaseExprForCase5413a() {
helpTestRewriteCriteria("pm1.g2.e1 = case when 0 = pm1.g1.e2 then 2 else 2 end", "pm1.g2.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -1515,6 +1515,16 @@
ValidatorReport report = helpValidateInModeler("pm1.vsp42", sql, metadata); //$NON-NLS-1$
assertEquals("Expected report to have no validation failures", false, report.hasItems()); //$NON-NLS-1$
}
+
+ @Test public void testNonQueryAgg() throws Exception{
+ String sql = "CREATE VIRTUAL PROCEDURE BEGIN IF (max(pm1.vsp42.param1) > 0) SELECT 1 AS x; ELSE SELECT 0 AS x; END"; //$NON-NLS-1$
+
+ QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();
+
+ // Validate
+ ValidatorReport report = helpValidateInModeler("pm1.vsp42", sql, metadata); //$NON-NLS-1$
+ examineReport(sql, new String[] {"MAX(pm1.vsp42.param1)"}, report);
+ }
@Test public void testDefect14886() throws Exception{
String sql = "CREATE VIRTUAL PROCEDURE BEGIN END"; //$NON-NLS-1$
@@ -1888,5 +1898,13 @@
@Test public void testWindowFunctionWithNestedOrdering() {
helpValidate("SELECT xmlagg(xmlelement(name x, e1) order by e2) over () from pm1.g1", new String[] {"XMLAGG(XMLELEMENT(NAME x, e1) ORDER BY e2)"}, RealMetadataFactory.example1Cached());
}
+
+ @Test public void testWindowFunctionWithNestedaggAllowed() {
+ helpValidate("SELECT max(e1) over (order by max(e2)) from pm1.g1 group by e1", new String[] {}, RealMetadataFactory.example1Cached());
+ }
+ @Test public void testWindowFunctionWithNestedaggAllowed1() {
+ helpValidate("SELECT max(min(e1)) over (order by max(e2)) from pm1.g1 group by e1", new String[] {"MIN(e1)"}, RealMetadataFactory.example1Cached());
+ }
+
}
Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -22,16 +22,16 @@
package org.teiid.connector.visitor.util;
+import static org.junit.Assert.*;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
-import junit.framework.TestCase;
-
+import org.junit.Test;
import org.teiid.language.ColumnReference;
import org.teiid.language.Comparison;
import org.teiid.language.Expression;
@@ -41,25 +41,14 @@
import org.teiid.language.Select;
import org.teiid.language.Comparison.Operator;
import org.teiid.language.visitor.CollectorVisitor;
-
/**
*/
-public class TestCollectorVisitor extends TestCase {
+public class TestCollectorVisitor {
- /**
- * Constructor for TestElementCollectorVisitor.
- * @param name
- */
- public TestCollectorVisitor(String name) {
- super(name);
- }
-
- public Set getStringSet(Collection objs) {
- Set strings = new HashSet();
+ public Set<String> getStringSet(Collection<? extends Object> objs) {
+ Set<String> strings = new HashSet<String>();
- Iterator iter = objs.iterator();
- while(iter.hasNext()) {
- Object obj = iter.next();
+ for (Object obj : objs) {
if(obj == null) {
strings.add(null);
} else {
@@ -90,38 +79,38 @@
return q;
}
- public void testCollection1() {
+ @Test public void testCollection1() {
helpTestCollection(example1(), ColumnReference.class, new String[] {"g1.e1", "g1.e2" }); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testCollection2() {
+ @Test public void testCollection2() {
helpTestCollection(example1(), Function.class, new String[] {"length(g1.e2)" }); //$NON-NLS-1$
}
- public void testCollection3() {
+ @Test public void testCollection3() {
helpTestCollection(example1(), Expression.class, new String[] {"g1.e1", "g1.e2", "length(g1.e2)" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void helpTestElementsUsedByGroups(LanguageObject obj, String[] elements, String[] groups) {
- Set actualElements = getStringSet(CollectorVisitor.collectElements(obj));
- Set actualGroups = getStringSet(CollectorVisitor.collectGroupsUsedByElements(obj));
+ Set<String> actualElements = getStringSet(CollectorVisitor.collectElements(obj));
+ Set<String> actualGroups = getStringSet(CollectorVisitor.collectGroupsUsedByElements(obj));
- Set expectedElements = new HashSet(Arrays.asList(elements));
- Set expectedGroups = new HashSet(Arrays.asList(groups));
+ Set<String> expectedElements = new HashSet<String>(Arrays.asList(elements));
+ Set<String> expectedGroups = new HashSet<String>(Arrays.asList(groups));
assertEquals("Did not get expected elements", expectedElements, actualElements); //$NON-NLS-1$
assertEquals("Did not get expected groups", expectedGroups, actualGroups); //$NON-NLS-1$
}
- public void test1() {
+ @Test public void test1() {
NamedTable g1 = new NamedTable("g1", null, null); //$NON-NLS-1$
ColumnReference e1 = new ColumnReference(g1, "e1", null, String.class); //$NON-NLS-1$
helpTestElementsUsedByGroups(e1, new String[] {"g1.e1"}, new String[] {"g1"}); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void test2() {
+ @Test public void test2() {
NamedTable g1 = new NamedTable("g1", null, null); //$NON-NLS-1$
ColumnReference e1 = new ColumnReference(g1, "e1", null, String.class); //$NON-NLS-1$
ColumnReference e2 = new ColumnReference(g1, "e2", null, String.class); //$NON-NLS-1$
Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java 2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java 2011-07-22 21:13:20 UTC (rev 3330)
@@ -73,7 +73,7 @@
import org.teiid.query.sql.lang.CompareCriteria;
import org.teiid.query.sql.lang.JoinType;
-
+@SuppressWarnings("nls")
public class TestSQLStringVisitor {
public static final RuntimeMetadata metadata = TstLanguageBridgeFactory.metadataFactory;
@@ -425,5 +425,12 @@
Command command = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(sql, true, true);
assertEquals("SELECT g_0.IntKey AS c_0 FROM SmallA AS g_0 ORDER BY c_0 NULLS FIRST", command.toString()); //$NON-NLS-1$
}
+
+ @Test public void testWindowFunction() throws Exception {
+ String sql = "select max(intnum) over (order by intkey nulls first) from bqt1.smalla";
+
+ Command command = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(sql, true, true);
+ assertEquals("SELECT MAX(g_0.IntNum) OVER (ORDER BY g_0.IntKey NULLS FIRST) FROM SmallA AS g_0", command.toString()); //$NON-NLS-1$
+ }
}
13 years, 5 months
teiid SVN: r3329 - in branches/7.4.x/engine/src: main/java/org/teiid/query/sql/symbol and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-22 15:03:28 -0400 (Fri, 22 Jul 2011)
New Revision: 3329
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
branches/7.4.x/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
Log:
TEIID-1645 re-enabling agg rewrite optimization
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22 18:50:01 UTC (rev 3328)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22 19:03:28 UTC (rev 3329)
@@ -2362,7 +2362,8 @@
expression.setAggregateFunction(Type.MAX);
}
}
- if (rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
+ if ((expression.getAggregateFunction() == Type.MAX || expression.getAggregateFunction() == Type.MIN)
+ && rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
return expression.getExpression();
}
return expression;
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java 2011-07-22 18:50:01 UTC (rev 3328)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java 2011-07-22 19:03:28 UTC (rev 3329)
@@ -254,16 +254,14 @@
return false;
}
switch (getAggregateFunction()) {
- case COUNT:
- case AVG:
- case STDDEV_POP:
- case STDDEV_SAMP:
- case VAR_POP:
- case VAR_SAMP:
- case SUM:
- return true;
+ case MAX:
+ case MIN:
+ case ANY:
+ case SOME:
+ case EVERY:
+ return false;
}
- return false;
+ return true;
}
public static boolean areAggregatesCardinalityDependent(Collection<AggregateSymbol> aggs) {
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22 18:50:01 UTC (rev 3328)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22 19:03:28 UTC (rev 3329)
@@ -2465,5 +2465,8 @@
helpTestRewriteCommand("select max(1) from pm1.g1 group by e1", "SELECT 1 FROM pm1.g1 GROUP BY e1");
}
+ @Test public void testRewriteConstantAgg2() throws Exception {
+ helpTestRewriteCommand("select count(2) from pm1.g1 group by e1", "SELECT COUNT(2) FROM pm1.g1 GROUP BY e1");
+ }
}
13 years, 5 months
teiid SVN: r3328 - in trunk/engine/src: test/java/org/teiid/query/optimizer and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-22 14:50:01 -0400 (Fri, 22 Jul 2011)
New Revision: 3328
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
Log:
TEIID-1665 optimizing grouping of all constants
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java 2011-07-22 16:26:08 UTC (rev 3327)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java 2011-07-22 18:50:01 UTC (rev 3328)
@@ -165,14 +165,6 @@
assignOutputElements(root.getLastChild(), outputElements, metadata, capFinder, rules, analysisRecord, context);
break;
case NodeConstants.Types.SOURCE: {
- if (outputElements.isEmpty()) {
- //we cannot completely filter an implicit grouping (this is a corner case)
- PlanNode grouping = NodeEditor.findNodePreOrder(root.getFirstChild(), NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE | NodeConstants.Types.JOIN);
- if (grouping != null && !grouping.hasCollectionProperty(NodeConstants.Info.GROUP_COLS)) {
- SymbolMap symbolMap = (SymbolMap) root.getProperty(NodeConstants.Info.SYMBOL_MAP);
- outputElements.add(symbolMap.getKeys().get(0).clone());
- }
- }
outputElements = (List<SingleElementSymbol>)determineSourceOutput(root, outputElements, metadata, capFinder);
root.setProperty(NodeConstants.Info.OUTPUT_COLS, outputElements);
List<SingleElementSymbol> childElements = filterVirtualElements(root, outputElements, metadata);
@@ -227,24 +219,27 @@
PlanNode next = root.getFirstChild();
NodeEditor.removeChildNode(root.getParent(), root);
- if (old.hasCollectionProperty(Info.GROUP_COLS)) {
- SymbolMap symbolMap = (SymbolMap) old.getProperty(NodeConstants.Info.SYMBOL_MAP);
- FrameUtil.convertFrame(next.getParent(), symbolMap.asMap().keySet().iterator().next().getGroupSymbol(), null, symbolMap.asMap(), metadata);
- PlanNode limit = NodeFactory.getNewNode(NodeConstants.Types.TUPLE_LIMIT);
- limit.setProperty(Info.MAX_TUPLE_LIMIT, new Constant(1));
- PlanNode parent = next.getParent();
- while (parent.getParent() != null && parent.getParent().getType() != NodeConstants.Types.SOURCE) {
- parent = parent.getParent();
- }
+ SymbolMap symbolMap = (SymbolMap) old.getProperty(NodeConstants.Info.SYMBOL_MAP);
+ FrameUtil.convertFrame(next.getParent(), symbolMap.asMap().keySet().iterator().next().getGroupSymbol(), null, symbolMap.asMap(), metadata);
+ PlanNode parent = next.getParent();
+ while (parent.getParent() != null && parent.getParent().getType() != NodeConstants.Types.SOURCE) {
+ parent = parent.getParent();
+ }
+ if (!old.hasCollectionProperty(Info.GROUP_COLS)) {
+ //just lob off everything under the projection
+ PlanNode project = NodeEditor.findNodePreOrder(parent, NodeConstants.Types.PROJECT);
+ project.removeAllChildren();
+ } else {
+ PlanNode limit = NodeFactory.getNewNode(NodeConstants.Types.TUPLE_LIMIT);
+ limit.setProperty(Info.MAX_TUPLE_LIMIT, new Constant(1));
if (!rules.contains(RuleConstants.PUSH_LIMIT)) {
rules.push(RuleConstants.PUSH_LIMIT);
}
- parent.getFirstChild().addAsParent(limit);
- execute(parent, metadata, capFinder, rules, analysisRecord, context);
- return;
- }
- root = next;
- }
+ parent.getFirstChild().addAsParent(limit);
+ }
+ execute(parent, metadata, capFinder, rules, analysisRecord, context);
+ return;
+ }
// Call children recursively
if(root.getChildCount() == 1) {
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-07-22 16:26:08 UTC (rev 3327)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-07-22 18:50:01 UTC (rev 3328)
@@ -984,7 +984,7 @@
@Test public void testDefect5282_2() {
helpPlan("select count(*) FROM vm1.a4", example1(), //$NON-NLS-1$
- new String[] { "SELECT 1 FROM pm1.g1" } ); //$NON-NLS-1$
+ new String[] { } ); //$NON-NLS-1$
}
@Test public void testDefect5282_3() {
@@ -6604,10 +6604,9 @@
bac.setCapabilitySupport(Capability.QUERY_FROM_INLINE_VIEWS, true);
bac.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, true);
bac.setCapabilitySupport(Capability.QUERY_GROUP_BY, true);
- helpPlan("select count(*) from agg3", metadata, new String[] {"SELECT COUNT(*) FROM (SELECT COUNT(*) AS c_0 FROM BQT1.SmallA AS g_0) AS v_0"}, new DefaultCapabilitiesFinder(bac), ComparisonMode.EXACT_COMMAND_STRING);
+ helpPlan("select count(*) from agg3", metadata, new String[] {}, new DefaultCapabilitiesFinder(bac), ComparisonMode.EXACT_COMMAND_STRING);
}
-
@Test public void testMergeGroupBy1() throws Exception {
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
13 years, 5 months
teiid SVN: r3327 - in trunk: api/src/main/java/org/teiid/language/visitor and 36 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-22 12:26:08 -0400 (Fri, 22 Jul 2011)
New Revision: 3327
Added:
trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected
Modified:
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java
trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml
trunk/engine/pom.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java
trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java
trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java
trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
trunk/pom.xml
trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected
trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected
Log:
forward merge of 7.4.1
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -284,8 +284,7 @@
if(elementID != null) {
elemShortName = getName(elementID);
} else {
- String elementName = obj.getName();
- elemShortName = getShortName(elementName);
+ elemShortName = obj.getName();
}
// Check whether a subclass wants to replace the element name to use in special circumstances
Modified: trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
===================================================================
--- trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -85,7 +85,7 @@
<!-- Hibernate 2LC can replicate custom types, so we use marshalling -->
<property name="useRegionBasedMarshalling">true</property>
<!-- Must match the value of "useRegionBasedMarshalling" -->
- <property name="inactiveOnStartup">true</property>
+ <property name="inactiveOnStartup">false</property>
<!-- Disable asynchronous RPC marshalling/sending -->
<property name="serializationExecutorPoolSize">0</property>
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-07-22 16:26:08 UTC (rev 3327)
@@ -34,7 +34,9 @@
<LI><B>Streaming XQuery</B> - in situations where document projection applies if the XMLQUERY/XMLTABLE path expressions meet certain conditions, then the incoming document will not only be projected, but the independent subtrees will be processed without loading the entire document. This allows for nearly arbitrarily large XML documents to be processed. See the Reference for more.
<LI><B>Logging Procedures</B> - added SYSADMIN.isLoggable and SYSADMIN.logMsg to aid in debugging procedure logic.
<LI><B>ANSI OFFSET/FETCH FIRST</B> - instead of the limit clause, a standard OFFSET and/or FETCH FIRST/NEXT clause can be used to limit results.
+ <LI><B>ODBC Cursors</B> - Capability to use "UseDeclareFetch" with ODBC is added. This enables user to read the results in batches, especially useful when dealing with large row count of results.
</UL>
+
<h2><a name="Compatibility">Compatibility Issues</a></h2>
<ul>
<li>TRANSLATE/HAS CRITERIA has been deprecated. An alternative approach to update procedures will be introduced in a subsequent version.
@@ -45,6 +47,8 @@
<h4>from 7.4</h4>
<ul>
<li>OFFSET was added as a keyword.
+ <li>ColumnReference.getName will always return just the element name. Previously it inconsistently returned the qualified and unqualified form depending upon where the ColumnReference appeared.
+ <li>As per JDBC4, ResultSetMetadata.getColumnName will return the unaliased column name if available rather than return the alias. Set useJDBC4ColumnNameAndLabelSemantics to false to use the alias name as the column name.
</ul>
<h4>from 7.3</h4>
Modified: trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
===================================================================
--- trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -59,6 +59,7 @@
if (!this.cacheStore.getCacheStatus().allowInvocations()) {
this.cacheStore.start();
+ this.cacheStore.getRegion(this.cacheStore.getRoot().getFqn(), true).activate();
}
Node cacheRoot = this.cacheStore.getRoot().addChild(Fqn.fromString("Teiid")); //$NON-NLS-1$
@@ -67,6 +68,7 @@
Region cacheRegion = this.cacheStore.getRegion(node.getFqn(), true);
cacheRegion.setEvictionRegionConfig(buildEvictionConfig(node.getFqn(), config));
+ cacheRegion.activate();
JBossCache jc = null;
if (config != null && config.getPolicy().equals(Policy.EXPIRATION)) {
Modified: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -1433,18 +1433,21 @@
// query string to be submitted to get table metadata info
StringBuffer sqlQuery = new StringBuffer(QUERY_TABLES);
- StringBuffer typesString = new StringBuffer("("); // criteria string for different table types //$NON-NLS-1$
-
if (types != null) {
- // construct the criteria string
- for(int i=0; i < types.length; i++) {
- if (types[i] != null && types[i].length() > 0) {
- if (i > 0) {
- typesString.append(" OR "); //$NON-NLS-1$
- }
- typesString.append(TABLE_TYPE).append(LIKE_ESCAPE);
- }
- }
+ StringBuffer typesString = new StringBuffer("("); // criteria string for different table types //$NON-NLS-1$
+ if (types.length == 0) {
+ typesString.append("1 = 0"); //$NON-NLS-1$
+ } else {
+ // construct the criteria string
+ for(int i=0; i < types.length; i++) {
+ if (types[i] != null && types[i].length() > 0) {
+ if (i > 0) {
+ typesString.append(" OR "); //$NON-NLS-1$
+ }
+ typesString.append(TABLE_TYPE).append(LIKE_ESCAPE);
+ }
+ }
+ }
typesString.append(")"); //$NON-NLS-1$
sqlQuery.append(" AND ").append(typesString.toString()); //$NON-NLS-1$
}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java:3281-3325
Modified: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -58,7 +58,8 @@
ExecutionProperties.PROP_XML_FORMAT,
ExecutionProperties.PROP_XML_VALIDATION,
EmbeddedProfile.USE_CALLING_THREAD,
- ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS)));
+ ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS,
+ ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS)));
public static final Set<String> KNOWN_PROPERTIES = getKnownProperties();
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java:3149-3217
+ /branches/7.4.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java:3149-3217,3281-3325
Modified: trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -39,7 +39,9 @@
public ResultSetMetaDataImpl(MetadataProvider provider, String supportBackwardsCompatibility) {
this.provider = provider;
- this.useJDBC4ColumnNameAndLabelSemantics = (supportBackwardsCompatibility != null && supportBackwardsCompatibility.equalsIgnoreCase("false") ? false : true);
+ if (supportBackwardsCompatibility != null) {
+ this.useJDBC4ColumnNameAndLabelSemantics = Boolean.parseBoolean(supportBackwardsCompatibility);
+ }
}
/**
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java:3281-3325
Modified: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -40,8 +40,6 @@
import java.util.Properties;
import java.util.TimeZone;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -538,11 +536,7 @@
});
if (synch) {
try {
- if (queryTimeoutMS > 0) {
- pendingResult.get(queryTimeoutMS, TimeUnit.MILLISECONDS);
- } else {
- pendingResult.get();
- }
+ pendingResult.get();
result.get(); //throw an exception if needed
return result;
} catch (ExecutionException e) {
@@ -552,8 +546,6 @@
throw TeiidSQLException.create(e);
} catch (InterruptedException e) {
timeoutOccurred();
- } catch (TimeoutException e) {
- timeoutOccurred();
}
throw new TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Timeout_before_complete")); //$NON-NLS-1$
}
@@ -578,7 +570,7 @@
reqMsg.setExecutionId(this.currentRequestID);
ResultsFuture.CompletionListener<ResultsMessage> compeletionListener = null;
- if (queryTimeoutMS > 0 && !synch) {
+ if (queryTimeoutMS > 0) {
final CancelTask c = new QueryTimeoutCancelTask(queryTimeoutMS, this);
cancellationTimer.add(c);
compeletionListener = new ResultsFuture.CompletionListener<ResultsMessage>() {
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java:3149-3217,3220-3275
+ /branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java:3149-3217,3220-3275,3281-3325
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -22,7 +22,8 @@
package org.teiid.jdbc;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.stub;
import java.sql.SQLException;
import java.util.Properties;
@@ -38,8 +39,6 @@
import org.teiid.client.util.ResultsFuture;
import org.teiid.client.xa.XATransactionException;
import org.teiid.client.xa.XidImpl;
-import org.teiid.jdbc.BaseDataSource;
-import org.teiid.jdbc.ConnectionImpl;
import org.teiid.net.ServerConnection;
@@ -48,13 +47,28 @@
protected static final String STD_DATABASE_NAME = "QT_Ora9DS"; //$NON-NLS-1$
protected static final int STD_DATABASE_VERSION = 1;
- static String serverUrl = "jdbc:metamatrix:QT_Ora9DS@mm://localhost:7001;version=1;user=metamatrixadmin;password=mm"; //$NON-NLS-1$
+ static String serverUrl = "jdbc:teiid:QT_Ora9DS@mm://localhost:7001;version=1;user=metamatrixadmin;password=mm"; //$NON-NLS-1$
public TestConnection(String name) {
super(name);
}
+ static class InnerDriver extends TeiidDriver {
+ String iurl = null;
+ public InnerDriver(String url) {
+ iurl = url;
+ }
+
+ public void parseUrl(Properties props) throws SQLException {
+ super.parseURL(iurl, props);
+ }
+ }
+
public static ConnectionImpl getMMConnection() {
+ return getMMConnection(serverUrl);
+ }
+
+ public static ConnectionImpl getMMConnection(String url) {
ServerConnection mock = mock(ServerConnection.class);
DQP dqp = mock(DQP.class);
try {
@@ -79,13 +93,20 @@
} catch (XATransactionException e) {
throw new RuntimeException(e);
}
+
+ Properties props = new Properties();
+
+ try {
+ new InnerDriver(url).parseUrl(props);
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
stub(mock.getService(DQP.class)).toReturn(dqp);
- Properties props = new Properties();
- props.setProperty(BaseDataSource.VDB_NAME, STD_DATABASE_NAME);
- props.setProperty(BaseDataSource.VDB_VERSION, String.valueOf(STD_DATABASE_VERSION));
- props.setProperty(BaseDataSource.USER_NAME, "metamatrixadmin"); //$NON-NLS-1$
- stub(mock.getLogonResult()).toReturn(new LogonResult(new SessionToken(1, "metamatrixadmin"), STD_DATABASE_NAME,STD_DATABASE_VERSION , "fake")); //$NON-NLS-1$
- return new ConnectionImpl(mock, props, serverUrl);
+
+ stub(mock.getLogonResult()).toReturn(new LogonResult(new SessionToken(1, "admin"), STD_DATABASE_NAME,STD_DATABASE_VERSION , "fake")); //$NON-NLS-1$
+ return new ConnectionImpl(mock, props, url);
}
public void testGetMetaData() throws Exception {
@@ -103,7 +124,7 @@
/** test getUserName() through DriverManager */
public void testGetUserName2() throws Exception {
- assertEquals("Actual userName is not equal to the expected one. ", "metamatrixadmin", getMMConnection().getUserName()); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("Actual userName is not equal to the expected one. ", "admin", getMMConnection().getUserName()); //$NON-NLS-1$ //$NON-NLS-2$
}
/** test isReadOnly default value on Connection */
@@ -129,4 +150,27 @@
// error expected
}
}
+
+ /**
+ * Test the default of the JDBC4 spec semantics is true
+ */
+ public void testDefaultSpec() throws Exception {
+ assertEquals("true",
+ (getMMConnection().getExecutionProperties().getProperty(ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS) == null ? "true" : "false"));
+ }
+
+ /**
+ * Test turning off the JDBC 4 semantics
+ */
+ public void testTurnOnSpec() throws Exception {
+ assertEquals("true", getMMConnection(serverUrl + ";useJDBC4ColumnNameAndLabelSemantics=true").getExecutionProperties().getProperty(ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS));
+ }
+
+ /**
+ * Test turning off the JDBC 4 semantics
+ */
+ public void testTurnOffSpec() throws Exception {
+ assertEquals("false", getMMConnection(serverUrl + ";useJDBC4ColumnNameAndLabelSemantics=false").getExecutionProperties().getProperty(ExecutionProperties.JDBC4COLUMNNAMEANDLABELSEMANTICS));
+ }
+
}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestConnection.java
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/client/src/test/java/org/teiid/jdbc/TestConnection.java:3281-3325
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -138,7 +138,7 @@
@Test public void testGetPropertyInfo1() throws Exception {
DriverPropertyInfo info[] = drv.getPropertyInfo("jdbc:teiid:vdb@mm://localhost:12345;applicationName=x", null); //$NON-NLS-1$
- assertEquals(20, info.length);
+ assertEquals(21, info.length);
assertEquals(false, info[0].required);
assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
assertEquals("x", info[0].value); //$NON-NLS-1$
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java:3149-3217
+ /branches/7.4.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java:3149-3217,3281-3325
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -24,6 +24,8 @@
*/
package org.teiid.translator.jdbc.sqlserver;
+import java.sql.Date;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -203,8 +205,16 @@
}
@Override
+ public String translateLiteralDate(Date dateValue) {
+ if (getDatabaseVersion().compareTo(V_2008) >= 0) {
+ return super.translateLiteralDate(dateValue);
+ }
+ return super.translateLiteralTimestamp(new Timestamp(dateValue.getTime()));
+ }
+
+ @Override
public boolean hasTimeType() {
- return getDatabaseVersion().compareTo(V_2005) >= 0;
+ return getDatabaseVersion().compareTo(V_2008) >= 0;
}
@Override
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -29,13 +29,21 @@
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.teiid.language.ColumnReference;
+import org.teiid.language.Command;
+import org.teiid.language.DerivedColumn;
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.LanguageFactory;
import org.teiid.language.Literal;
+import org.teiid.language.QueryExpression;
+import org.teiid.language.Select;
+import org.teiid.language.SortSpecification;
+import org.teiid.translator.ExecutionContext;
import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
@@ -107,21 +115,12 @@
convert.addNumericBooleanConversions();
registerFunctionModifier(SourceSystemFunctions.CONVERT, convert);
- registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new SubstrModifier(this.convert));
+ registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("substr")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.RAND, new AliasModifier("random")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.LOG, new AliasModifier("LN")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LCASE, new StringOnlyModifier("LOWER", this.convert)); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.UCASE, new StringOnlyModifier("UPPER", this.convert)); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LENGTH, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
- target.add("character_length("); //$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- });
+ registerFunctionModifier(SourceSystemFunctions.LCASE, new AliasModifier("LOWER")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("UPPER")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LENGTH, new AliasModifier("character_length")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CURDATE, new AliasModifier("CURRENT_DATE")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CURTIME, new AliasModifier("CURRENT_TIME")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.YEAR, new ExtractModifier("YEAR")); //$NON-NLS-1$
@@ -143,9 +142,9 @@
registerFunctionModifier(SourceSystemFunctions.LTRIM, new FunctionModifier() {
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
target.add("TRIM(LEADING FROM ");//$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
+ target.add(function.getParameters().get(0));
target.add(")"); //$NON-NLS-1$
return target;
}
@@ -153,9 +152,9 @@
registerFunctionModifier(SourceSystemFunctions.RTRIM, new FunctionModifier() {
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
target.add("TRIM(TRAILING FROM ");//$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
+ target.add(function.getParameters().get(0));
target.add(")"); //$NON-NLS-1$
return target;
}
@@ -216,7 +215,7 @@
@Override
- public List getSupportedFunctions() {
+ public List<String> getSupportedFunctions() {
List<String> supportedFunctions = new ArrayList<String>();
supportedFunctions.addAll(super.getSupportedFunctions());
@@ -317,8 +316,37 @@
}
@Override
- public boolean supportsSetQueryOrderBy() {
- return false;
+ public List<?> translateCommand(Command command, ExecutionContext context) {
+ if (command instanceof QueryExpression) {
+ QueryExpression qe = (QueryExpression)command;
+ //teradata prefers positional ordering
+ if (qe.getOrderBy() != null) {
+ Select select = qe.getProjectedQuery();
+ List<DerivedColumn> derivedColumns = select.getDerivedColumns();
+ Map<String, Integer> positions = new HashMap<String, Integer>();
+ int i = 1;
+ for (DerivedColumn derivedColumn : derivedColumns) {
+ String name = derivedColumn.getAlias();
+ if (name == null && derivedColumn.getExpression() instanceof ColumnReference) {
+ ColumnReference cr = (ColumnReference)derivedColumn.getExpression();
+ name = cr.toString();
+ }
+ positions.put(name, i++);
+ }
+ for (SortSpecification ss : qe.getOrderBy().getSortSpecifications()) {
+ Expression ex = ss.getExpression();
+ if (!(ex instanceof ColumnReference)) {
+ continue;
+ }
+ ColumnReference cr = (ColumnReference)ex;
+ Integer position = positions.get(cr.toString());
+ if (position != null) {
+ ss.setExpression(new Literal(position, TypeFacility.RUNTIME_TYPES.INTEGER));
+ }
+ }
+ }
+ }
+ return super.translateCommand(command, context);
}
public static class LocateModifier extends FunctionModifier {
@@ -330,67 +358,31 @@
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
Expression expr1 = function.getParameters().get(0);
Expression expr2 = function.getParameters().get(1);
if (function.getParameters().size() > 2) {
Expression expr3 = function.getParameters().get(2);
target.add("position("); //$NON-NLS-1$
- target.addAll(expressionToString(expr1, this.convertModifier));
+ target.add(expr1);
target.add( " in "); //$NON-NLS-1$
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(expr2, this.convertModifier));
+ target.add(expr2);
target.add(","); //$NON-NLS-1$
target.add(expr3);
target.add("))"); //$NON-NLS-1$
}
else {
target.add("position("); //$NON-NLS-1$
- target.addAll(expressionToString(expr1, this.convertModifier));
+ target.add(expr1);
target.add( " in "); //$NON-NLS-1$
- target.addAll(expressionToString(expr2, this.convertModifier));
+ target.add(expr2);
target.add(")"); //$NON-NLS-1$
}
return target;
}
}
- private static List<?> expressionToString(Expression expr, ConvertModifier modifier) {
- Class tgtType = expr.getType();
- if (tgtType.equals(String.class) && ((expr instanceof Literal) || expr instanceof ColumnReference)) {
- return Arrays.asList(expr);
- }
- else if (tgtType.equals(String.class) && (expr instanceof Function)) {
-
- Function func = (Function)expr;
- while(true) {
- Expression arg1 = func.getParameters().get(0);
- if ((arg1 instanceof Function) && ((Function)arg1).getName().equals("convert")) { //$NON-NLS-1$
- func = (Function)arg1;
- }
- else {
- break;
- }
- }
- Expression arg1 = func.getParameters().get(0);
- if (arg1 instanceof ColumnReference) {
- ColumnReference ref = (ColumnReference)func.getParameters().get(0);
- if(Number.class.isAssignableFrom(ref.getType())) {
- ArrayList target = new ArrayList();
- target.add("cast("); //$NON-NLS-1$
- target.add(func.getParameters().get(0));
- target.add(" AS varchar(100))"); //$NON-NLS-1$
- return target;
- }
- else if (String.class.isAssignableFrom(ref.getType())) {
- return Arrays.asList(ref);
- }
- }
- return modifier.translate(func);
- }
- return Arrays.asList("cast(" , expr, " AS varchar(100))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
public static class ExtractModifier extends FunctionModifier {
private String type;
public ExtractModifier(String type) {
@@ -413,47 +405,6 @@
}
}
- public static class StringOnlyModifier extends FunctionModifier {
- String funcName;
- ConvertModifier convertModifier;
- public StringOnlyModifier(String name, ConvertModifier converModifier) {
- this.funcName = name;
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add(this.funcName);
- target.add("("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
-
- public static class SubstrModifier extends FunctionModifier {
- ConvertModifier convertModifier;
- public SubstrModifier(ConvertModifier converModifier) {
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(","); //$NON-NLS-1$
- target.add(function.getParameters().get(1));
- if (function.getParameters().size() > 2 ) {
- target.add(","); //$NON-NLS-1$
- target.add(function.getParameters().get(2));
- }
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
-
public static class LeftOrRightFunctionModifier extends FunctionModifier {
private LanguageFactory langFactory;
ConvertModifier convertModifier;
@@ -466,11 +417,11 @@
@Override
public List<?> translate(Function function) {
List<Expression> args = function.getParameters();
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
if (function.getName().equalsIgnoreCase("left")) { //$NON-NLS-1$
//substr(string, 1, length)
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(","); //$NON-NLS-1$
target.add(langFactory.createLiteral(Integer.valueOf(1), TypeFacility.RUNTIME_TYPES.INTEGER));
target.add(","); //$NON-NLS-1$
@@ -479,10 +430,10 @@
} else if (function.getName().equalsIgnoreCase("right")) { //$NON-NLS-1$
//substr(case_size, character_length(case_size) -4)
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(",(character_length("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(")-"); //$NON-NLS-1$
target.add(args.get(1));
target.add("+1))"); //$NON-NLS-1$ // offset for 1 based index
@@ -491,22 +442,4 @@
}
}
- public static class UpperOrLowerModifier extends FunctionModifier {
- String funcName;
- ConvertModifier convertModifier;
- public UpperOrLowerModifier(String name, ConvertModifier converModifier) {
- this.funcName = name;
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add(this.funcName);
- target.add("("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
}
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -49,9 +49,13 @@
private static SQLServerExecutionFactory trans = new SQLServerExecutionFactory();
@BeforeClass
- public static void setup() throws TranslatorException {
+ public static void oneTimeSetup() throws TranslatorException {
trans.start();
}
+
+ public void setUp() throws Exception {
+ trans.setDatabaseVersion(SQLServerExecutionFactory.V_2005);
+ }
public String getTestVDB() {
return TranslationHelper.PARTS_VDB;
@@ -143,6 +147,25 @@
output);
}
+ @Test public void testConvertDate() throws Exception {
+ String input = "select stringkey from bqt1.smalla where BQT1.SmallA.DateValue IN (convert('2000-01-12', date), convert('2000-02-02', date))"; //$NON-NLS-1$
+ String output = "SELECT SmallA.StringKey FROM SmallA WHERE SmallA.DateValue IN (CAST('2000-01-12 00:00:00.0' AS DATETIME), CAST('2000-02-02 00:00:00.0' AS DATETIME))"; //$NON-NLS-1$
+
+ helpTestVisitor(getBQTVDB(),
+ input,
+ output);
+ }
+
+ @Test public void testConvertDate2008() throws Exception {
+ trans.setDatabaseVersion(SQLServerExecutionFactory.V_2008);
+ String input = "select stringkey from bqt1.smalla where BQT1.SmallA.DateValue IN (convert('2000-01-12', date), convert('2000-02-02', date))"; //$NON-NLS-1$
+ String output = "SELECT SmallA.StringKey FROM SmallA WHERE SmallA.DateValue IN (CAST('2000-01-12' AS DATE), CAST('2000-02-02' AS DATE))"; //$NON-NLS-1$
+
+ helpTestVisitor(getBQTVDB(),
+ input,
+ output);
+ }
+
@Test public void testUniqueidentifier() throws Exception {
MetadataStore metadataStore = new MetadataStore();
Schema foo = RealMetadataFactory.createPhysicalModel("foo", metadataStore); //$NON-NLS-1$
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -31,6 +31,8 @@
import org.junit.BeforeClass;
import org.junit.Test;
+import org.teiid.cdk.api.TranslationUtility;
+import org.teiid.language.Command;
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.In;
@@ -82,35 +84,61 @@
@Test public void testIntegerToString() throws Exception {
String input = "SELECT lcase(bigdecimalvalue) FROM BQT1.SMALLA";
- String output = "SELECT LOWER(cast(SmallA.BigDecimalValue AS varchar(100))) FROM SmallA";
+ String output = "SELECT LOWER(cast(SmallA.BigDecimalValue AS varchar(4000))) FROM SmallA";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@Test public void testSubString() throws Exception {
String input = "SELECT intkey FROM BQT1.SmallA WHERE SUBSTRING(BQT1.SmallA.IntKey, 1) = '1' ORDER BY intkey";
- String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(100)),1) = '1' ORDER BY SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(4000)), 1) = '1' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@Test public void testSubString2() throws Exception {
String input = "SELECT intkey FROM BQT1.SmallA WHERE SUBSTRING(BQT1.SmallA.IntKey, 1, 2) = '1' ORDER BY intkey";
- String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(100)),1,2) = '1' ORDER BY SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(4000)), 1, 2) = '1' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@Test public void testDateToString() throws Exception {
String input = "SELECT intkey, UPPER(timevalue) AS UPPER FROM BQT1.SmallA ORDER BY intkey";
- String output = "SELECT SmallA.IntKey, UPPER(cast(cast(SmallA.TimeValue AS FORMAT 'HH:MI:SS') AS VARCHAR(9))) AS UPPER FROM SmallA ORDER BY SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey, UPPER(cast(cast(SmallA.TimeValue AS FORMAT 'HH:MI:SS') AS VARCHAR(9))) AS UPPER FROM SmallA ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@Test public void testLocate() throws Exception {
String input = "SELECT INTKEY, BIGDECIMALVALUE FROM BQT1.SmallA WHERE LOCATE('-', BIGDECIMALVALUE) = 1 ORDER BY intkey";
- String output = "SELECT SmallA.IntKey, SmallA.BigDecimalValue FROM SmallA WHERE position('-' in cast(SmallA.BigDecimalValue AS varchar(100))) = 1 ORDER BY SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey, SmallA.BigDecimalValue FROM SmallA WHERE position('-' in cast(SmallA.BigDecimalValue AS varchar(4000))) = 1 ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
+ @Test public void testPositionalOrderBy() throws Exception {
+ String input = "SELECT INTKEY, BIGDECIMALVALUE FROM BQT1.SmallA ORDER BY intkey";
+ String output = "SELECT g_0.IntKey AS c_0, g_0.BigDecimalValue AS c_1 FROM SmallA AS g_0 ORDER BY 1";
+
+ TranslationUtility tu = TranslationHelper.getTranslationUtility(TranslationHelper.BQT_VDB, null);
+ Command command = tu.parseCommand(input, true, true);
+ TranslationHelper.helpTestVisitor(output, TRANSLATOR, command);
+ }
+ @Test public void testPositionalOrderByUnion() throws Exception {
+ String input = "SELECT a as b, b as a from (SELECT intkey as a, stringkey as b from BQT1.smalla union SELECT intkey as a, stringkey as b from BQT1.smalla) as x order by a";
+ String output = "SELECT v_0.c_0, v_0.c_1 FROM (SELECT g_1.IntKey AS c_0, g_1.StringKey AS c_1 FROM SmallA AS g_1 UNION SELECT g_0.IntKey AS c_0, g_0.StringKey AS c_1 FROM SmallA AS g_0) AS v_0 ORDER BY 2";
+
+ TranslationUtility tu = TranslationHelper.getTranslationUtility(TranslationHelper.BQT_VDB, null);
+ Command command = tu.parseCommand(input, true, true);
+ TranslationHelper.helpTestVisitor(output, TRANSLATOR, command);
+ }
+
+ @Test public void testPositionalOrderByUnion1() throws Exception {
+ String input = "SELECT a as b from (SELECT intkey as a, stringkey as b from BQT1.smalla union SELECT intkey as a, stringkey as b from BQT1.smalla) as x order by x.b";
+ String output = "SELECT v_0.c_0 FROM (SELECT g_1.IntKey AS c_0, g_1.StringKey AS c_1 FROM SmallA AS g_1 UNION SELECT g_0.IntKey AS c_0, g_0.StringKey AS c_1 FROM SmallA AS g_0) AS v_0 ORDER BY v_0.c_1";
+
+ TranslationUtility tu = TranslationHelper.getTranslationUtility(TranslationHelper.BQT_VDB, null);
+ Command command = tu.parseCommand(input, true, true);
+ TranslationHelper.helpTestVisitor(output, TRANSLATOR, command);
+ }
+
@Test public void testByteToString() throws Exception {
helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "string", "cast(1 AS varchar(4000))");
}
@@ -194,13 +222,13 @@
@Test public void testRightFunction() throws Exception {
String input = "SELECT INTKEY, FLOATNUM FROM BQT1.SmallA WHERE right(FLOATNUM, 2) <> 0 ORDER BY INTKEY";
- String out = "SELECT SmallA.IntKey, SmallA.FloatNum FROM SmallA WHERE substr(cast(SmallA.FloatNum AS varchar(100)),(character_length(cast(SmallA.FloatNum AS varchar(100)))-2+1)) <> '0' ORDER BY SmallA.IntKey";
+ String out = "SELECT SmallA.IntKey, SmallA.FloatNum FROM SmallA WHERE substr(cast(SmallA.FloatNum AS varchar(4000)),(character_length(cast(SmallA.FloatNum AS varchar(4000)))-2+1)) <> '0' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, null, input, out, TRANSLATOR);
}
@Test public void testLocateFunction() throws Exception {
String input = "SELECT INTKEY, STRINGKEY, SHORTVALUE FROM BQT1.SmallA WHERE (LOCATE(0, STRINGKEY) = 2) OR (LOCATE(2, SHORTVALUE, 4) = 6) ORDER BY intkey";
- String out = "SELECT SmallA.IntKey, SmallA.StringKey, SmallA.ShortValue FROM SmallA WHERE position('0' in SmallA.StringKey) = 2 OR position('2' in substr(cast(SmallA.ShortValue AS varchar(100)),4)) = 6 ORDER BY SmallA.IntKey";
+ String out = "SELECT SmallA.IntKey, SmallA.StringKey, SmallA.ShortValue FROM SmallA WHERE position('0' in SmallA.StringKey) = 2 OR position('2' in substr(cast(SmallA.ShortValue AS varchar(4000)),4)) = 6 ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, null, input, out, TRANSLATOR);
}
}
Modified: trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
===================================================================
--- trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -250,10 +250,9 @@
<code>boolean</code>
</entry>
<entry>
- <para>A change was made in JDBC4 so that when an 'Alias' is used it will
- now be returned as the label. Prior to this, it was returned as
- the name. Setting this property to false will enable
- backwards compatibility when JDBC3 and older support is still required.
+ <para>A change was made in JDBC4 to return unaliased column names as the ResultSetMetadata column name.
+ Prior to this, if a column alias were used it was returned as the column name. Setting this property to false will enable
+ backwards compatibility when JDBC3 and older support is still required. Defaults to true.
</para>
</entry>
</row>
Modified: trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml
===================================================================
--- trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -175,11 +175,7 @@
<code>JDBC4COLUMNNAMEANDLABELSEMANTICS / useJDBC4ColumnNameAndLabelSemantics</code>
</entry>
<entry>
- <para>A change was made in JDBC4 so that when an 'Alias' is used it will.
- now be returned as the label. Prior to this, it was returned as
- the name. Setting this property to false will enable
- backwards compatibility when JDBC3 and older support is still required.
- </para>
+ <para>Same as the connection property.</para>
</entry>
</row>
</tbody>
Modified: trunk/engine/pom.xml
===================================================================
--- trunk/engine/pom.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/pom.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -78,14 +78,8 @@
<dependency>
<groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
+ <artifactId>saxonhe</artifactId>
</dependency>
-
- <dependency>
- <groupId>net.sourceforge.saxon</groupId>
- <classifier>dom</classifier>
- <artifactId>saxon</artifactId>
- </dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
@@ -106,4 +100,4 @@
</dependencies>
-</project>
\ No newline at end of file
+</project>
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -115,6 +115,7 @@
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
+import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.translator.TranslatorException;
@@ -179,9 +180,9 @@
/* Query */
Select translate(Query query) {
- List symbols = query.getSelect().getSymbols();
+ List<SelectSymbol> symbols = query.getSelect().getSymbols();
List<DerivedColumn> translatedSymbols = new ArrayList<DerivedColumn>(symbols.size());
- for (Iterator i = symbols.iterator(); i.hasNext();) {
+ for (Iterator<SelectSymbol> i = symbols.iterator(); i.hasNext();) {
SingleElementSymbol symbol = (SingleElementSymbol)i.next();
String alias = null;
if(symbol instanceof AliasSymbol) {
@@ -375,7 +376,7 @@
In translate(SetCriteria criteria) {
Collection expressions = criteria.getValues();
- List translatedExpressions = new ArrayList();
+ List<org.teiid.language.Expression> translatedExpressions = new ArrayList<org.teiid.language.Expression>();
for (Iterator i = expressions.iterator(); i.hasNext();) {
translatedExpressions.add(translate((Expression)i.next()));
}
@@ -423,13 +424,13 @@
return new SubqueryComparison(translate(criteria.getLeftExpression()),
operator,
quantifier,
- translate((QueryCommand)criteria.getCommand()));
+ translate(criteria.getCommand()));
}
SubqueryIn translate(SubquerySetCriteria criteria) {
return new SubqueryIn(translate(criteria.getExpression()),
criteria.isNegated(),
- translate((QueryCommand)criteria.getCommand()));
+ translate(criteria.getCommand()));
}
Not translate(NotCriteria criteria) {
@@ -462,7 +463,7 @@
if(items.get(i).isUnrelated() || (!set && symbol instanceof ElementSymbol)){
orderByItem = new SortSpecification(direction, translate(symbol));
} else {
- orderByItem = new SortSpecification(direction, new ColumnReference(null, symbol.getOutputName(), null, symbol.getType()));
+ orderByItem = new SortSpecification(direction, new ColumnReference(null, SingleElementSymbol.getShortName(symbol.getOutputName()), null, symbol.getType()));
}
orderByItem.setNullOrdering(items.get(i).getNullOrdering());
translatedItems.add(orderByItem);
@@ -558,7 +559,7 @@
}
ColumnReference translate(ElementSymbol symbol) {
- ColumnReference element = new ColumnReference(translate(symbol.getGroupSymbol()), symbol.getOutputName(), null, symbol.getType());
+ ColumnReference element = new ColumnReference(translate(symbol.getGroupSymbol()), SingleElementSymbol.getShortName(symbol.getOutputName()), null, symbol.getType());
if (element.getTable().getMetadataObject() == null) {
return element;
}
@@ -746,10 +747,10 @@
/* Batched Updates */
BatchedUpdates translate(BatchedUpdateCommand command) {
- List updates = command.getUpdateCommands();
+ List<Command> updates = command.getUpdateCommands();
List<org.teiid.language.Command> translatedUpdates = new ArrayList<org.teiid.language.Command>(updates.size());
- for (Iterator i = updates.iterator(); i.hasNext();) {
- translatedUpdates.add(translate((Command)i.next()));
+ for (Iterator<Command> i = updates.iterator(); i.hasNext();) {
+ translatedUpdates.add(translate(i.next()));
}
return new BatchedUpdates(translatedUpdates);
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/AbstractWorkItem.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -26,7 +26,6 @@
import javax.resource.spi.work.WorkEvent;
import javax.resource.spi.work.WorkListener;
-import org.teiid.core.TeiidRuntimeException;
import org.teiid.logging.LogManager;
@@ -43,23 +42,14 @@
private ThreadState threadState = ThreadState.MORE_WORK;
private volatile boolean isProcessing;
- private Thread callingThread;
- public AbstractWorkItem(Thread callingThread) {
- this.callingThread = callingThread;
- }
-
public void run() {
- do {
- startProcessing();
- try {
- process();
- } finally {
- if (!endProcessing()) {
- break;
- }
- }
- } while (!isDoneProcessing());
+ startProcessing();
+ try {
+ process();
+ } finally {
+ endProcessing();
+ }
}
synchronized ThreadState getThreadState() {
@@ -79,10 +69,7 @@
this.threadState = ThreadState.WORKING;
}
- /**
- * @return true if processing should be continued
- */
- final private synchronized boolean endProcessing() {
+ private synchronized void endProcessing() {
isProcessing = false;
logTrace("end processing"); //$NON-NLS-1$
switch (this.threadState) {
@@ -92,21 +79,20 @@
this.threadState = ThreadState.DONE;
} else {
this.threadState = ThreadState.IDLE;
- return pauseProcessing();
+ pauseProcessing();
}
break;
case MORE_WORK:
if (isDoneProcessing()) {
logTrace("done processing - ignoring more"); //$NON-NLS-1$
this.threadState = ThreadState.DONE;
- } else if (this.callingThread == null) {
- resumeProcessing();
+ } else {
+ resumeProcessing();
}
break;
default:
throw new IllegalStateException("Should not END on " + this.threadState); //$NON-NLS-1$
}
- return this.callingThread != null;
}
protected boolean isIdle() {
@@ -117,8 +103,9 @@
moreWork(true);
}
- final protected synchronized void moreWork(boolean ignoreDone) {
+ protected synchronized void moreWork(boolean ignoreDone) {
logTrace("more work"); //$NON-NLS-1$
+ this.notifyAll();
switch (this.threadState) {
case WORKING:
this.threadState = ThreadState.MORE_WORK;
@@ -127,15 +114,7 @@
break;
case IDLE:
this.threadState = ThreadState.MORE_WORK;
- if (this.callingThread != null) {
- if (this.callingThread == Thread.currentThread()) {
- run(); //restart with the calling thread
- } else {
- this.notifyAll(); //notify the waiting caller
- }
- } else {
- resumeProcessing();
- }
+ resumeProcessing();
break;
default:
if (!ignoreDone) {
@@ -151,33 +130,8 @@
protected abstract void process();
- protected boolean pauseProcessing() {
- if (this.callingThread != null && !shouldPause()) {
- return false;
- }
- while (this.callingThread != null && this.getThreadState() == ThreadState.IDLE) {
- try {
- this.wait(); //the lock should already be held
- } catch (InterruptedException e) {
- interrupted(e);
- }
- }
- return this.callingThread != null;
+ protected void pauseProcessing() {
}
-
- /**
- * only called for synch processing
- */
- protected boolean shouldPause() {
- return false;
- }
-
- /**
- * only called for synch processing
- */
- protected void interrupted(InterruptedException e) {
- throw new TeiidRuntimeException(e);
- }
protected abstract void resumeProcessing();
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -93,9 +93,11 @@
private long creationTime = System.currentTimeMillis();
private DQPWorkContext workContext = DQPWorkContext.getWorkContext();
private List<CompletionListener<T>> completionListeners = new LinkedList<CompletionListener<T>>();
+ private String parentName;
public FutureWork(final Callable<T> processor, int priority) {
super(processor);
+ this.parentName = Thread.currentThread().getName();
this.priority = priority;
}
@@ -105,6 +107,12 @@
}
@Override
+ public void run() {
+ LogManager.logDetail(LogConstants.CTX_DQP, "Running task for parent thread", parentName); //$NON-NLS-1$
+ super.run();
+ }
+
+ @Override
public int getPriority() {
return priority;
}
@@ -344,6 +352,7 @@
}
}
if (runInThread) {
+ workItem.useCallingThread = true;
workItem.run();
}
return resultsFuture;
@@ -721,6 +730,8 @@
processorDataManager.setMetadataRepository(metadataRepository);
dataTierMgr = new TempTableDataManager(processorDataManager, this.bufferManager, this.processWorkerPool, this.rsCache, this.matTables, this.cacheFactory);
dataTierMgr.setEventDistributor(eventDistributor);
+
+ LogManager.logDetail(LogConstants.CTX_DQP, "DQPCore started maxThreads", this.config.getMaxThreads(), "maxActivePlans", this.maxActivePlans, "source concurrency", this.userRequestSourceConcurrency); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void setBufferService(BufferService service) {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -188,11 +188,8 @@
}
public void runInContext(final Runnable runnable) {
- DQPWorkContext.setWorkContext(this);
- boolean associated = false;
- if (securityHelper != null && this.getSubject() != null) {
- associated = securityHelper.assosiateSecurityContext(this.getSecurityDomain(), this.getSecurityContext());
- }
+ DQPWorkContext previous = DQPWorkContext.getWorkContext();
+ boolean associated = attachDQPWorkContext();
try {
runnable.run();
} finally {
@@ -200,9 +197,21 @@
securityHelper.clearSecurityContext(this.getSecurityDomain());
}
DQPWorkContext.releaseWorkContext();
+ if (previous != null) {
+ previous.attachDQPWorkContext();
+ }
}
}
+ private boolean attachDQPWorkContext() {
+ DQPWorkContext.setWorkContext(this);
+ boolean associated = false;
+ if (securityHelper != null && this.getSubject() != null) {
+ associated = securityHelper.assosiateSecurityContext(this.getSecurityDomain(), this.getSecurityContext());
+ }
+ return associated;
+ }
+
public HashMap<String, DataPolicy> getAllowedDataPolicies() {
if (this.policies == null) {
this.policies = new HashMap<String, DataPolicy>();
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -162,8 +162,10 @@
/**The time when command begins processing on the server.*/
private long processingTimestamp = System.currentTimeMillis();
+ protected boolean useCallingThread;
+ private volatile boolean hasThread;
+
public RequestWorkItem(DQPCore dqpCore, RequestMessage requestMsg, Request request, ResultsReceiver<ResultsMessage> receiver, RequestID requestID, DQPWorkContext workContext) {
- super(workContext.useCallingThread() || requestMsg.isSync() ? Thread.currentThread() : null);
this.requestMsg = requestMsg;
this.requestID = requestID;
this.processorTimeslice = dqpCore.getProcessorTimeSlice();
@@ -196,24 +198,65 @@
protected boolean isDoneProcessing() {
return isClosed;
}
+
+ @Override
+ public void run() {
+ hasThread = true;
+ try {
+ while (!isDoneProcessing()) {
+ super.run();
+ if (!useCallingThread) {
+ break;
+ }
+ //should use the calling thread
+ synchronized (this) {
+ if (this.resultsReceiver == null) {
+ break; //allow results to be processed by calling thread
+ }
+ if (this.getThreadState() == ThreadState.MORE_WORK) {
+ continue;
+ }
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ try {
+ requestCancel();
+ } catch (TeiidComponentException e1) {
+ throw new TeiidRuntimeException(e1);
+ }
+ }
+ }
+ }
+ } finally {
+ hasThread = false;
+ }
+ }
@Override
protected void resumeProcessing() {
- if (doneProducingBatches && !closeRequested && !isCanceled) {
- this.run(); // just run in the IO thread
- } else {
+ if (!this.useCallingThread) {
dqpCore.addWork(this);
}
}
- @Override
- protected void interrupted(InterruptedException e) {
- try {
- this.requestCancel();
- } catch (TeiidComponentException e1) {
- throw new TeiidRuntimeException(e1);
+ /**
+ * Special call from request threads to allow resumption of processing by
+ * the calling thread.
+ */
+ public void doMoreWork() {
+ boolean run = false;
+ synchronized (this) {
+ moreWork();
+ if (!useCallingThread || this.getThreadState() != ThreadState.MORE_WORK) {
+ return;
+ }
+ run = !hasThread;
}
- super.interrupted(e);
+ if (run) {
+ //run outside of the lock
+ LogManager.logDetail(LogConstants.CTX_DQP, "Restarting processing using the calling thread", requestID); //$NON-NLS-1$
+ run();
+ }
}
@Override
@@ -293,7 +336,7 @@
}
private void suspend() {
- if (this.transactionState == TransactionState.ACTIVE && this.transactionContext.getTransaction() != null) {
+ if ((this.transactionState != TransactionState.NONE) && this.transactionContext.getTransaction() != null) {
try {
this.transactionService.suspend(this.transactionContext);
} catch (XATransactionException e) {
@@ -650,12 +693,6 @@
return new TeiidProcessingException(exception, SQLStates.QUERY_CANCELED, exception.getMessage());
}
- @Override
- protected boolean shouldPause() {
- //if we are waiting on results it's ok to pause
- return this.resultsReceiver != null;
- }
-
private static List<ParameterInfo> getParameterInfo(StoredProcedure procedure) {
List<ParameterInfo> paramInfos = new ArrayList<ParameterInfo>();
@@ -750,12 +787,12 @@
if (!this.doneProducingBatches) {
this.requestCancel(); //pending work should be canceled for fastest clean up
}
- this.moreWork();
+ this.doMoreWork();
}
public void requestMore(int batchFirst, int batchLast, ResultsReceiver<ResultsMessage> receiver) {
this.requestResults(batchFirst, batchLast, receiver);
- this.moreWork();
+ this.doMoreWork();
}
public void closeAtomicRequest(AtomicRequestID atomicRequestId) {
Modified: trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/mapping/xml/MappingNode.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -25,8 +25,8 @@
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -214,7 +214,7 @@
*/
public Map<MappingNodeConstants.Properties, Object> getNodeProperties(){
if(nodeProperties == null) {
- nodeProperties = new HashMap<MappingNodeConstants.Properties, Object>();
+ nodeProperties = new LinkedHashMap<MappingNodeConstants.Properties, Object>();
}
return nodeProperties;
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -43,7 +43,6 @@
public static final int SET_OP = 1<<8;
public static final int NULL = 1<<9;
public static final int TUPLE_LIMIT = 1<<10;
- public static final int WITH = 1<<11;
}
/**
@@ -64,7 +63,6 @@
case NodeConstants.Types.SET_OP: return "SetOperation"; //$NON-NLS-1$
case NodeConstants.Types.NULL: return "Null"; //$NON-NLS-1$
case NodeConstants.Types.TUPLE_LIMIT: return "TupleLimit"; //$NON-NLS-1$
- case NodeConstants.Types.WITH: return "With"; //$NON-NLS-1$
default: return "Unknown: " + type; //$NON-NLS-1$
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -37,7 +37,6 @@
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
-import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.util.Assertion;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -50,17 +49,21 @@
import org.teiid.query.resolver.util.AccessPattern;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.CompoundCriteria;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.GroupBy;
import org.teiid.query.sql.lang.OrderBy;
+import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.lang.QueryCommand;
import org.teiid.query.sql.lang.Select;
import org.teiid.query.sql.lang.StoredProcedure;
+import org.teiid.query.sql.symbol.AliasSymbol;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.ExpressionSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
@@ -125,15 +128,15 @@
}
static boolean canConvertAccessPatterns(PlanNode sourceNode) {
- List accessPatterns = (List)sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
+ List<AccessPattern> accessPatterns = (List)sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
if (accessPatterns == null) {
return true;
}
SymbolMap symbolMap = (SymbolMap)sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
- for (Iterator i = accessPatterns.iterator(); i.hasNext();) {
- AccessPattern ap = (AccessPattern)i.next();
- for (Iterator elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<AccessPattern> i = accessPatterns.iterator(); i.hasNext();) {
+ AccessPattern ap = i.next();
+ for (Iterator<ElementSymbol> elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap.asMap());
if (ElementCollectorVisitor.getElements(mapped, true).isEmpty()) {
return false;
@@ -154,15 +157,15 @@
if (accessPatterns != null) {
for (AccessPattern ap : accessPatterns) {
Set<ElementSymbol> newElements = new HashSet<ElementSymbol>();
- for (Iterator elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<ElementSymbol> elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap);
newElements.addAll(ElementCollectorVisitor.getElements(mapped, true));
}
ap.setUnsatisfied(newElements);
Set<ElementSymbol> newHistory = new HashSet<ElementSymbol>();
- for (Iterator elems = ap.getCurrentElements().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<ElementSymbol> elems = ap.getCurrentElements().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap);
newHistory.addAll(ElementCollectorVisitor.getElements(mapped, true));
}
@@ -233,6 +236,11 @@
List<SingleElementSymbol> projectedSymbols = (List<SingleElementSymbol>)node.getProperty(NodeConstants.Info.PROJECT_COLS);
Select select = new Select(projectedSymbols);
ExpressionMappingVisitor.mapExpressions(select, symbolMap);
+ if (rewrite) {
+ for (LanguageObject expr : select.getSymbols()) {
+ rewriteSingleElementSymbol(metadata, (SingleElementSymbol) expr);
+ }
+ }
node.setProperty(NodeConstants.Info.PROJECT_COLS, select.getSymbols());
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(select, groups);
@@ -257,6 +265,11 @@
} else if(type == NodeConstants.Types.SORT) {
OrderBy orderBy = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
ExpressionMappingVisitor.mapExpressions(orderBy, symbolMap);
+ if (rewrite) {
+ for (OrderByItem item : orderBy.getOrderByItems()) {
+ rewriteSingleElementSymbol(metadata, item.getSymbol());
+ }
+ }
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(orderBy, groups);
}
@@ -278,6 +291,25 @@
convertAccessPatterns(symbolMap, node);
}
}
+
+ private static void rewriteSingleElementSymbol(
+ QueryMetadataInterface metadata, SingleElementSymbol ses) throws QueryPlannerException {
+ try {
+ if (ses instanceof AliasSymbol) {
+ ses = ((AliasSymbol)ses).getSymbol();
+ }
+ if (ses instanceof ExpressionSymbol) {
+ ExpressionSymbol es = (ExpressionSymbol)ses;
+ if (es.getExpression() != null) {
+ es.setExpression(QueryRewriter.rewriteExpression(es.getExpression(), null, null, metadata));
+ }
+ }
+ } catch(TeiidProcessingException e) {
+ throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", ses)); //$NON-NLS-1$
+ } catch (TeiidComponentException e) {
+ throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", ses)); //$NON-NLS-1$
+ }
+ }
private static Expression convertExpression(Expression expression, Map symbolMap) {
@@ -314,7 +346,7 @@
} catch(TeiidProcessingException e) {
throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", criteria)); //$NON-NLS-1$
} catch (TeiidComponentException e) {
- throw new TeiidRuntimeException(e);
+ throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", criteria)); //$NON-NLS-1$
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -419,11 +419,11 @@
result.type = crit.getClass();
result.not = exists.isNegated();
//the correlations can only be in where (if no group by or aggregates) or having
- result.query = (Query)exists.getCommand();
result.mergeJoin = exists.getSubqueryHint().isMergeJoin();
if (!UNNEST && !result.mergeJoin) {
return result;
}
+ result.query = (Query)exists.getCommand();
}
return result;
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -52,6 +52,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.Transform;
import org.teiid.core.util.Assertion;
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.SQLConstants.NonReserved;
@@ -148,7 +149,6 @@
import org.teiid.query.sql.symbol.Reference;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
-import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.symbol.AggregateSymbol.Type;
import org.teiid.query.sql.util.SymbolMap;
@@ -240,6 +240,7 @@
* @throws QueryValidatorException
*/
private Command rewriteCommand(Command command, boolean removeOrderBy) throws TeiidComponentException, TeiidProcessingException{
+ boolean oldRewriteAggs = rewriteAggs;
QueryMetadataInterface oldMetadata = metadata;
CreateUpdateProcedureCommand oldProcCommand = procCommand;
@@ -299,6 +300,7 @@
break;
}
+ this.rewriteAggs = oldRewriteAggs;
this.metadata = oldMetadata;
this.procCommand = oldProcCommand;
return command;
@@ -605,9 +607,9 @@
From from = query.getFrom();
if(from != null){
List<FromClause> clauses = new ArrayList<FromClause>(from.getClauses().size());
- Iterator clauseIter = from.getClauses().iterator();
+ Iterator<FromClause> clauseIter = from.getClauses().iterator();
while(clauseIter.hasNext()) {
- clauses.add( rewriteFromClause(query, (FromClause) clauseIter.next()) );
+ clauses.add( rewriteFromClause(query, clauseIter.next()) );
}
from.setClauses(clauses);
} else {
@@ -765,6 +767,7 @@
*/
private Query rewriteGroupBy(Query query) throws TeiidComponentException, TeiidProcessingException {
if (query.getGroupBy() == null) {
+ rewriteAggs = false;
return query;
}
if (isDistinctWithGroupBy(query)) {
@@ -811,11 +814,11 @@
try {
PostOrderNavigator.doVisit(obj, visitor);
} catch (TeiidRuntimeException err) {
- if (err.getChild() instanceof TeiidComponentException) {
- throw (TeiidComponentException)err.getChild();
+ if (err.getCause() instanceof TeiidComponentException) {
+ throw (TeiidComponentException)err.getCause();
}
- if (err.getChild() instanceof TeiidProcessingException) {
- throw (TeiidProcessingException)err.getChild();
+ if (err.getCause() instanceof TeiidProcessingException) {
+ throw (TeiidProcessingException)err.getCause();
}
throw err;
}
@@ -1552,6 +1555,7 @@
private BigDecimal BIG_DECIMAL_ZERO = new BigDecimal("0"); //$NON-NLS-1$
private Short SHORT_ZERO = new Short((short)0);
private Byte BYTE_ZERO = new Byte((byte)0);
+ private boolean rewriteAggs = true;
/**
* @param criteria
@@ -2246,6 +2250,9 @@
expression.setAggregateFunction(Type.MAX);
}
}
+ if (rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
+ return expression.getExpression();
+ }
if (expression.getExpression() != null && expression.getCondition() != null && !expression.respectsNulls()) {
Expression cond = expression.getCondition();
Expression ex = expression.getExpression();
@@ -2414,17 +2421,44 @@
}
function.setArgs(newArgs);
- if( FunctionLibrary.isConvert(function) &&
- newArgs[1] instanceof Constant) {
-
- Class srcType = newArgs[0].getType();
- String tgtTypeName = (String) ((Constant)newArgs[1]).getValue();
- Class tgtType = DataTypeManager.getDataTypeClass(tgtTypeName);
+ if( FunctionLibrary.isConvert(function)) {
+ Class<?> srcType = newArgs[0].getType();
+ Class<?> tgtType = function.getType();
if(srcType != null && tgtType != null && srcType.equals(tgtType)) {
- return newArgs[0];
+ return newArgs[0]; //unnecessary conversion
}
-
+
+ if (!(newArgs[0] instanceof Function) || tgtType == DataTypeManager.DefaultDataClasses.OBJECT) {
+ return function;
+ }
+ Function nested = (Function) newArgs[0];
+ if (!FunctionLibrary.isConvert(nested)) {
+ return function;
+ }
+ Class<?> nestedType = nested.getArgs()[0].getType();
+
+ Transform t = DataTypeManager.getTransform(nestedType, nested.getType());
+ if (t.isExplicit()) {
+ //explicit conversions are required
+ return function;
+ }
+ if (DataTypeManager.getTransform(nestedType, tgtType) == null) {
+ //no direct conversion exists
+ return function;
+ }
+ //can't remove a convert that would alter the lexical form
+ if (tgtType == DataTypeManager.DefaultDataClasses.STRING &&
+ (nestedType == DataTypeManager.DefaultDataClasses.BOOLEAN
+ || nestedType == DataTypeManager.DefaultDataClasses.DATE
+ || nestedType == DataTypeManager.DefaultDataClasses.TIME
+ || tgtType == DataTypeManager.DefaultDataClasses.BIG_DECIMAL
+ || tgtType == DataTypeManager.DefaultDataClasses.FLOAT
+ || (tgtType == DataTypeManager.DefaultDataClasses.DOUBLE && srcType != DataTypeManager.DefaultDataClasses.FLOAT))) {
+ return function;
+ }
+ //nested implicit transform is not needed
+ return rewriteExpressionDirect(ResolverUtil.getConversion(nested.getArgs()[0], DataTypeManager.getDataTypeName(nestedType), DataTypeManager.getDataTypeName(tgtType), false, funcLibrary));
}
//convert DECODESTRING function to CASE expression
@@ -2702,7 +2736,7 @@
select.setSymbols(select.getProjectedSymbols());
- List<SelectSymbol> symbols = select.getSymbols();
+ List symbols = select.getSymbols();
HashSet<String> uniqueNames = new HashSet<String>();
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/QueryString.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -30,7 +30,7 @@
import org.teiid.query.sql.visitor.SQLStringVisitor;
/**
- * Represents XMLATTRIBUTES name value pairs
+ * Represents query string name value pairs
*/
public class QueryString implements Expression {
Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -37,6 +37,8 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.language.SQLConstants;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
@@ -96,6 +98,7 @@
public synchronized MatState setState(MatState state, Boolean valid, Long timestamp) {
MatState oldState = this.state;
+ LogManager.logDetail(LogConstants.CTX_MATVIEWS, this, "setting matState to", state, valid, timestamp, "old values", oldState, this.valid); //$NON-NLS-1$ //$NON-NLS-2$
if (valid != null) {
this.valid = valid;
}
Modified: trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -404,7 +404,7 @@
String groupName = es.getGroupSymbol().getCanonicalName();
UpdateMapping info = updateInfo.updatableGroups.get(groupName);
if (es.getGroupSymbol().getDefinition() != null) {
- ElementSymbol clone = (ElementSymbol)es.clone();
+ ElementSymbol clone = es.clone();
clone.setOutputName(null);
clone.getGroupSymbol().setName(clone.getGroupSymbol().getNonCorrelationName());
clone.getGroupSymbol().setDefinition(null);
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -115,7 +115,7 @@
* @return the unique number identifying this document within the name pool
*/
- public int getDocumentNumber() {
+ public long getDocumentNumber() {
return documentNumber;
}
@@ -124,12 +124,16 @@
*
* @param id
* the required ID value
+ * @param getParent
+ * true if running the element-with-id() function rather than the id()
+ * function; the difference is that in the case of an element of type xs:ID,
+ * the parent of the element should be returned, not the element itself.
* @return the element with the given ID, or null if there is no such ID
* present (or if the parser has not notified attributes as being of
* type ID).
*/
- public NodeInfo selectID(String id) {
+ public NodeInfo selectID(String id, boolean getParent) {
if (idIndex == null) {
Element elem;
switch (nodeKind) {
@@ -145,7 +149,14 @@
idIndex = new HashMap(50);
buildIDIndex(elem);
}
- return (NodeInfo) idIndex.get(id);
+
+ NodeInfo result = (NodeInfo) idIndex.get(id);
+
+ if (result != null && getParent && result.isId() && result.getStringValue().equals(id)) {
+ result = result.getParent();
+ }
+
+ return result ;
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -160,6 +160,14 @@
}
/**
+ * Get the real XOM node, to implement the VirtualNode interface
+ */
+
+ public Object getRealNode() {
+ return node;
+ }
+
+ /**
* Get the name pool for this node
*
* @return the NamePool
@@ -799,7 +807,7 @@
* free-standing orphan node, just return the hashcode.
*/
- public int getDocumentNumber() {
+ public long getDocumentNumber() {
return docWrapper.getDocumentNumber();
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -256,6 +256,7 @@
public void close() throws XPathException {
reciever.close();
+ super.close();
}
public void comment(CharSequence content, int locationId, int properties)
@@ -265,6 +266,7 @@
public void endDocument() throws XPathException {
reciever.endDocument();
+ super.endDocument() ;
}
public void endElement() throws XPathException {
@@ -285,6 +287,7 @@
}
public void open() throws XPathException {
+ super.open();
reciever.open();
}
@@ -295,10 +298,12 @@
public void setPipelineConfiguration(PipelineConfiguration config) {
reciever.setPipelineConfiguration(config);
+ super.setPipelineConfiguration(config);
}
public void setSystemId(String systemId) {
reciever.setSystemId(systemId);
+ super.setSystemId(systemId);
}
public void setUnparsedEntity(String name, String systemID,
@@ -311,6 +316,7 @@
}
public void startDocument(int properties) throws XPathException {
+ super.startDocument(properties);
reciever.startDocument(properties);
}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-22 16:26:08 UTC (rev 3327)
@@ -232,7 +232,7 @@
ERR.015.004.0010= Unknown group specified in OPTION MAKEDEP/MAKENOTDEP: {0}
ERR.015.004.0012= Group has an access pattern which has not been met: group(s) {0}; access pattern(s) {1}
ERR.015.004.0020= Error getting model for {0}
-ERR.015.004.0023= Error rewriting criteria: {0}
+ERR.015.004.0023= Error rewriting: {0}
ERR.015.004.0024= Unable to create a query plan that sends a criteria to \"{0}\". This connection factory requires criteria set to true indicating that a query against this model requires criteria.
ERR.015.004.0029= Could not resolve group symbol {0}
ERR.015.004.0035= The criteria {0} has elements from the root staging table and the document nodes which is not allowed.
Modified: trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -33,7 +33,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.query.sql.symbol.ElementSymbol;
-@SuppressWarnings("nls")
+@SuppressWarnings({"nls", "unchecked"})
public class TestSTree {
@Test public void testRemoveAll() throws TeiidComponentException {
@@ -42,7 +42,7 @@
e1.setType(Integer.class);
ElementSymbol e2 = new ElementSymbol("y");
e2.setType(String.class);
- List elements = Arrays.asList(e1, e2);
+ List<ElementSymbol> elements = Arrays.asList(e1, e2);
STree map = bm.createSTree(elements, "1", 1);
for (int i = 20000; i > 0; i--) {
@@ -83,7 +83,7 @@
ElementSymbol e1 = new ElementSymbol("x");
e1.setType(Integer.class);
- List elements = Arrays.asList(e1);
+ List<ElementSymbol> elements = Arrays.asList(e1);
STree map = bm.createSTree(elements, "1", 1);
int size = (1<<16)+(1<<4)+1;
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeConnector.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -22,35 +22,25 @@
package org.teiid.dqp.internal.datamgr;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import junit.framework.Assert;
-
import org.teiid.language.Command;
-import org.teiid.language.QueryExpression;
import org.teiid.metadata.RuntimeMetadata;
-import org.teiid.translator.TranslatorException;
import org.teiid.translator.DataNotAvailableException;
import org.teiid.translator.Execution;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.TranslatorException;
import org.teiid.translator.UpdateExecution;
-public class FakeConnector extends ExecutionFactory {
- private static final int RESULT_SIZE = 5;
-
- private boolean executeBlocks;
- private boolean nextBatchBlocks;
- private boolean returnsFinalBatch;
- private boolean driverThrowsExceptionOnCancel;
- private long simulatedBatchRetrievalTime = 1000L;
- private ClassLoader classloader;
+public class FakeConnector extends ExecutionFactory<Object, Object> {
private int connectionCount;
private int executionCount;
-
+
public int getConnectionCount() {
return connectionCount;
}
@@ -62,123 +52,52 @@
@Override
public Execution createExecution(Command command, ExecutionContext executionContext, RuntimeMetadata metadata, Object connection) throws TranslatorException {
executionCount++;
- return new FakeBlockingExecution(executionContext);
+ return new FakeExecution(executionContext);
}
- public Object getConnection() {
- return new FakeConnection();
- }
-
@Override
public Object getConnection(Object factory) throws TranslatorException {
+ connectionCount++;
return factory;
}
@Override
public void closeConnection(Object connection, Object factory) {
}
-
- private class FakeConnection {
- public FakeConnection() {
- connectionCount++;
- }
-
- public boolean released = false;
- public void close() {
- Assert.assertFalse("The connection should not be released more than once", released); //$NON-NLS-1$
- released = true;
- }
- }
- private final class FakeBlockingExecution implements ResultSetExecution, UpdateExecution {
- private boolean closed = false;
- private boolean cancelled = false;
+ public final class FakeExecution implements ResultSetExecution, UpdateExecution {
private int rowCount;
ExecutionContext ec;
- public FakeBlockingExecution(ExecutionContext ec) {
+
+ public FakeExecution(ExecutionContext ec) {
this.ec = ec;
}
- public void execute(QueryExpression query, int maxBatchSize) throws TranslatorException {
- if (executeBlocks) {
- waitForCancel();
- }
- if (classloader != null) {
- Assert.assertSame(classloader, Thread.currentThread().getContextClassLoader());
- }
- }
- public synchronized void cancel() throws TranslatorException {
- cancelled = true;
- this.notify();
- }
- public void close() {
- Assert.assertFalse("The execution should not be closed more than once", closed); //$NON-NLS-1$
- closed = true;
- }
@Override
public void execute() throws TranslatorException {
ec.addWarning(new Exception("Some warning")); //$NON-NLS-1$
}
@Override
- public List next() throws TranslatorException, DataNotAvailableException {
- if (nextBatchBlocks) {
- waitForCancel();
- }
- if (this.rowCount >= RESULT_SIZE || returnsFinalBatch) {
+ public List<?> next() throws TranslatorException, DataNotAvailableException {
+ if (this.rowCount == 1) {
return null;
}
this.rowCount++;
- return Arrays.asList(this.rowCount - 1);
+ return new ArrayList<Object>(Arrays.asList(this.rowCount - 1));
}
- private synchronized void waitForCancel() throws TranslatorException {
- try {
- this.wait(simulatedBatchRetrievalTime);
- if (cancelled && driverThrowsExceptionOnCancel) {
- throw new TranslatorException("Request cancelled"); //$NON-NLS-1$
- }
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
@Override
public int[] getUpdateCounts() throws DataNotAvailableException,
TranslatorException {
return new int[] {1};
}
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public void cancel() throws TranslatorException {
+ }
}
- public boolean isExecuteBlocks() {
- return executeBlocks;
- }
- public void setExecuteBlocks(boolean executeBlocks) {
- this.executeBlocks = executeBlocks;
- }
- public boolean isNextBatchBlocks() {
- return nextBatchBlocks;
- }
- public void setNextBatchBlocks(boolean nextBatchBlocks) {
- this.nextBatchBlocks = nextBatchBlocks;
- }
- public boolean isReturnsFinalBatch() {
- return returnsFinalBatch;
- }
- public void setReturnsFinalBatch(boolean returnsFinalBatch) {
- this.returnsFinalBatch = returnsFinalBatch;
- }
- public boolean isDriverThrowsExceptionOnCancel() {
- return driverThrowsExceptionOnCancel;
- }
- public void setDriverThrowsExceptionOnCancel(
- boolean driverThrowsExceptionOnCancel) {
- this.driverThrowsExceptionOnCancel = driverThrowsExceptionOnCancel;
- }
- public long getSimulatedBatchRetrievalTime() {
- return simulatedBatchRetrievalTime;
- }
- public void setSimulatedBatchRetrievalTime(long simulatedBatchRetrievalTime) {
- this.simulatedBatchRetrievalTime = simulatedBatchRetrievalTime;
- }
- public void setClassloader(ClassLoader classloader) {
- this.classloader = classloader;
- }
}
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorManager.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -50,7 +50,7 @@
return c;
}
protected Object getConnectionFactory(){
- return c.getConnection();
+ return c;
}
};
cm.start();
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestConnectorWorkItem.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -87,7 +87,7 @@
int total_columns = 3;
StoredProcedure command = (StoredProcedure)helpGetCommand("{call pm2.spTest8(?)}", EXAMPLE_BQT); //$NON-NLS-1$
command.getInputParameters().get(0).setExpression(new Constant(1));
- Call proc = (Call)new LanguageBridgeFactory(EXAMPLE_BQT).translate(command);
+ Call proc = new LanguageBridgeFactory(EXAMPLE_BQT).translate(command);
ProcedureBatchHandler pbh = new ProcedureBatchHandler(proc, exec);
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/TestElementImpl.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -72,7 +72,7 @@
public void testGetName() throws Exception {
Object metadataID = TstLanguageBridgeFactory.metadata.getElementID("pm1.g1.e1"); //$NON-NLS-1$
- assertEquals("pm1.g1.e1", example("pm1.g1", "e1", metadataID).getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ assertEquals("e1", example("pm1.g1", "e1", metadataID).getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void testGetGroup() throws Exception {
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestWorkItemState.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -25,20 +25,10 @@
import static org.junit.Assert.*;
import org.junit.Test;
-import org.teiid.dqp.internal.process.AbstractWorkItem.ThreadState;
public class TestWorkItemState {
- private final class WorkItemRunner implements Runnable {
- TestWorkItem workItem;
-
- @Override
- public void run() {
- workItem.run();
- }
- }
-
private class TestWorkItem extends AbstractWorkItem {
private boolean isDone;
@@ -50,11 +40,6 @@
}
private TestWorkItem(boolean done, boolean callMoreWork) {
- this(done, callMoreWork, null);
- }
-
- private TestWorkItem(boolean done, boolean callMoreWork, Thread callingThread) {
- super(callingThread);
this.isDone = done;
this.callMoreWork = callMoreWork;
}
@@ -167,26 +152,4 @@
}
}
- @Test public void testUsingCallingThreadIdle() throws Exception {
- WorkItemRunner r = new WorkItemRunner();
- Thread t = new Thread(r);
- final TestWorkItem item = new TestWorkItem(false, false, t) {
- @Override
- protected boolean shouldPause() {
- return true;
- }
- };
- r.workItem = item;
- t.start();
- for (int i = 0; i < 10 && item.getThreadState() != ThreadState.IDLE; i++) {
- Thread.sleep(100);
- }
- if (item.getThreadState() != ThreadState.IDLE) {
- fail();
- }
- item.moreWork();
- //if we don't return from this call, that means that this thread has been hijacked -
- //we should instead use t.
- }
-
}
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -1000,9 +1000,10 @@
}
@Test public void testTimestampDiffTimeStamp_Day_1() throws Exception {
+ // Moving to June, March fails because of DST
helpTestTimestampDiff(NonReserved.SQL_TSI_DAY,
- TimestampUtil.createTimestamp((2004-1900), 2, 1, 0, 0, 0, 0),
- TimestampUtil.createTimestamp((2004-1900), 3, 1, 0, 0, 0, 0),
+ TimestampUtil.createTimestamp((2004-1900), 4, 1, 0, 0, 0, 0),
+ TimestampUtil.createTimestamp((2004-1900), 5, 1, 0, 0, 0, 0),
new Long(31));
}
Property changes on: trunk/engine/src/test/java/org/teiid/query/function/TestFunction.java
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/engine/src/test/java/org/teiid/query/function/TestFunction.java:3281-3325
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -757,6 +757,7 @@
}
@Test public void testSubqueryRewriteToJoinDistinct() throws Exception {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
TestQueryRewriter.helpTestRewriteCommand("Select distinct e1 from pm1.g1 as x where exists (select pm1.g1.e1 FROM pm1.g1 where e1 = x.e1)", "SELECT DISTINCT e1 FROM pm1.g1 AS x, (SELECT pm1.g1.e1 FROM pm1.g1) AS X__1 WHERE x.e1 = X__1.e1", RealMetadataFactory.example1Cached());
}
@@ -764,6 +765,7 @@
* Agg does not depend on cardinality
*/
@Test public void testSubqueryRewriteToJoinGroupBy() throws Exception {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
TestQueryRewriter.helpTestRewriteCommand("Select max(e1) from pm1.g1 as x where exists (select pm1.g1.e1 FROM pm1.g1 where e1 = x.e1) group by e2", "SELECT MAX(e1) FROM pm1.g1 AS x, (SELECT pm1.g1.e1 FROM pm1.g1) AS X__1 WHERE x.e1 = X__1.e1 GROUP BY e2", RealMetadataFactory.example1Cached());
}
@@ -775,6 +777,7 @@
}
@Test public void testSubqueryRewriteToJoin() throws Exception {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
TestQueryRewriter.helpTestRewriteCommand("Select e1 from pm3.g1 where exists (select pm1.g1.e1 FROM pm1.g1 where e1 = pm3.g1.e1)", "SELECT e1 FROM pm3.g1, (SELECT pm1.g1.e1 FROM pm1.g1) AS X__1 WHERE pm3.g1.e1 = X__1.e1", RealMetadataFactory.example4());
}
@@ -919,6 +922,7 @@
* Same as above, but the source is much larger, so a semi-join is favorable
*/
@Test public void testSemiJoinExistsCosting() {
+ System.setProperty(RuleMergeCriteria.UNNEST_DEFAULT, Boolean.TRUE.toString());
ProcessorPlan plan = helpPlan("Select e1 from pm2.g2 as o where not exists (select 1 from pm3.g1 where e1 = o.e1 having o.e2 = count(e2))", RealMetadataFactory.example4(), //$NON-NLS-1$
new String[] { "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm2.g2 AS g_0 ORDER BY c_0, c_1" }); //$NON-NLS-1$
checkNodeTypes(plan, new int[] {
Property changes on: trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java:3149-3217
+ /branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java:3149-3217,3281-3325
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -202,8 +202,8 @@
String sql = "select * from xmltable('/a/b' passing convert('<a><b>first</b><b x=\"1\">second</b></a>', xml) columns val xml path '.') as x"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList("<b>first</b>"),
- Arrays.asList("<b x=\"1\">second</b>"),
+ Arrays.asList("<b xmlns=\"\">first</b>"),
+ Arrays.asList("<b xmlns=\"\" x=\"1\">second</b>"),
};
process(sql, expected);
@@ -286,7 +286,7 @@
String sql = "select xmlquery('/a/b' passing xmlparse(document '<a><b x=''1''/><b x=''2''/></a>') null on empty)"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList("<b x=\"1\"/><b x=\"2\"/>")
+ Arrays.asList("<b xmlns=\"\" x=\"1\"/><b xmlns=\"\" x=\"2\"/>")
};
process(sql, expected);
Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java:3149-3217,3220-3275
+ /branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java:3149-3217,3220-3275,3281-3325
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -124,11 +124,11 @@
}
private Map<ElementSymbol, Integer> elements;
- private List<List> tuples;
+ private List<List<? extends Object>> tuples;
@Before public void setUp() {
elements = null;
- tuples = new ArrayList<List>();
+ tuples = new ArrayList<List<? extends Object>>();
}
private Criteria helpTestRewriteCriteria(String original, Criteria expectedCrit, QueryMetadataInterface metadata) {
@@ -138,7 +138,7 @@
// rewrite
try {
ArrayList<Boolean> booleanVals = new ArrayList<Boolean>(tuples.size());
- for (List<Object> tuple : tuples) {
+ for (List<?> tuple : tuples) {
booleanVals.add(new Evaluator(elements, null, null).evaluate(origCrit, tuple));
}
actual = QueryRewriter.rewriteCriteria(origCrit, null, null, metadata);
@@ -2085,10 +2085,6 @@
helpTestRewriteCriteria("concat2('a', pm1.g1.e1) = 'xyz'", "concat('a', ifnull(pm1.g1.e1, '')) = 'xyz'"); //$NON-NLS-1$ //$NON-NLS-2$
}
- @Test public void testRewiteEvaluatableAggregate() {
- helpTestRewriteCommand("select max(1) from pm1.g1", "SELECT MAX(1) FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
@Test public void testRewriteFromUnixTime() throws Exception {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$
try {
@@ -2448,5 +2444,21 @@
String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);
}
+
+ @Test public void testRewriteNestedConvert() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as integer) as long)", "cast(pm1.g1.e3 as long)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Test public void testRewriteNestedConvert1() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as integer) as string)", "convert(convert(pm1.g1.e3, integer), string)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ @Test public void testRewriteNestedConvert2() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as string) as clob)", "convert(convert(pm1.g1.e3, string), clob)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Test public void testRewriteConstantAgg() throws Exception {
+ helpTestRewriteCommand("select max(1) from pm1.g1 group by e1", "SELECT 1 FROM pm1.g1 GROUP BY e1");
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -419,6 +419,14 @@
new String[] {"COUNT(DISTINCT ObjectValue)"}, RealMetadataFactory.exampleBQTCached() ); //$NON-NLS-1$
}
+ /**
+ * previously failed on stringkey, which is not entirely correct
+ */
+ @Test public void testInvalidAggregate10() {
+ helpValidate("SELECT xmlparse(document stringkey) FROM BQT1.SmallA GROUP BY xmlparse(document stringkey)", //$NON-NLS-1$
+ new String[] {"XMLPARSE(DOCUMENT stringkey)"}, RealMetadataFactory.exampleBQTCached() ); //$NON-NLS-1$
+ }
+
@Test public void testInvalidAggregateIssue190644() {
helpValidate("SELECT e3 + 1 from pm1.g1 GROUP BY e2 + 1 HAVING e2 + 1 = 5", new String[] {"e3"}, RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -436,6 +444,11 @@
"FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000 +' else '0-999' end", //$NON-NLS-1$
new String[] {}, RealMetadataFactory.exampleBQTCached());
}
+
+ @Test public void testValidAggregate4() {
+ helpValidate("SELECT max(e1), e2 is null from pm1.g1 GROUP BY e2 is null", new String[] {}, RealMetadataFactory.example1Cached()); //$NON-NLS-1$
+ }
+
@Test public void testInvalidHaving1() {
helpValidate("SELECT e3 FROM test.group HAVING e3 > 0", new String[] {"e3"}, exampleMetadata()); //$NON-NLS-1$ //$NON-NLS-2$
}
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/pom.xml 2011-07-22 16:26:08 UTC (rev 3327)
@@ -439,16 +439,10 @@
</dependency>
<dependency>
<groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
- <version>9.1.0.8</version>
+ <artifactId>saxonhe</artifactId>
+ <version>9.2.1.5</version>
</dependency>
<dependency>
- <groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
- <classifier>dom</classifier>
- <version>9.1.0.8</version>
- </dependency>
- <dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.1.Final</version>
@@ -493,4 +487,4 @@
<url>https://repository.jboss.org/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
-</project>
\ No newline at end of file
+</project>
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -21,13 +21,14 @@
*/
package org.teiid.odbc;
+import java.io.IOException;
import java.sql.ParameterMetaData;
-import java.sql.ResultSetMetaData;
-import java.sql.Statement;
+import java.util.List;
import java.util.Properties;
import org.teiid.client.util.ResultsFuture;
import org.teiid.jdbc.ResultSetImpl;
+import org.teiid.odbc.PGUtil.PgColInfo;
public interface ODBCClientRemote {
@@ -62,11 +63,19 @@
// RowDescription (B)
// NoData (B)
- void sendResultSetDescription(ResultSetMetaData metaData, Statement stmt);
+ void sendResultSetDescription(List<PgColInfo> cols);
// DataRow (B)
// CommandComplete (B)
- void sendResults(String sql, ResultSetImpl rs, ResultsFuture<Void> result, boolean describeRows);
+ void sendResults(String sql, ResultSetImpl rs, List<PgColInfo> cols, ResultsFuture<Integer> result, boolean describeRows);
+
+ void sendCursorResults(ResultSetImpl rs, List<PgColInfo> cols, ResultsFuture<Integer> result, int rowCount);
+
+ void sendPortalResults(String sql, ResultSetImpl rs, List<PgColInfo> cols, ResultsFuture<Integer> result, int rowCount, boolean portal);
+
+ void sendMoveCursor(ResultSetImpl rs, int rowCount, ResultsFuture<Integer> results);
+
+ void sendCommandComplete(String sql, int updateCount) throws IOException;
// CommandComplete (B)
void sendUpdateCount(String sql, int updateCount);
@@ -106,8 +115,5 @@
// NoticeResponse (B)
// NotificationResponse (B)
- // PortalSuspended (B)
-
-
-
+ void sendPortalSuspended();
}
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -21,14 +21,19 @@
*/
package org.teiid.odbc;
+import static org.teiid.odbc.PGUtil.convertType;
+
import java.io.IOException;
import java.io.StringReader;
import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
@@ -40,10 +45,12 @@
import org.teiid.core.util.StringUtil;
import org.teiid.jdbc.ConnectionImpl;
import org.teiid.jdbc.PreparedStatementImpl;
+import org.teiid.jdbc.ResultSetImpl;
import org.teiid.jdbc.StatementImpl;
import org.teiid.jdbc.TeiidDriver;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
+import org.teiid.odbc.PGUtil.PgColInfo;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.transport.ODBCClientInstance;
@@ -133,11 +140,17 @@
private static Pattern preparedAutoIncrement = Pattern.compile("select 1 \\s*from pg_catalog.pg_attrdef \\s*where adrelid = \\$1 AND adnum = \\$2 " + //$NON-NLS-1$
"\\s*and pg_catalog.pg_get_expr\\(adbin, adrelid\\) \\s*like '%nextval\\(%'", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
- private static Pattern deallocatePattern = Pattern.compile("DEALLOCATE \"(\\w+\\d+_*)\""); //$NON-NLS-1$
- private static Pattern releasePattern = Pattern.compile("RELEASE (\\w+\\d+_*)"); //$NON-NLS-1$
- private static Pattern savepointPattern = Pattern.compile("SAVEPOINT (\\w+\\d+_*)"); //$NON-NLS-1$
- private static Pattern rollbackPattern = Pattern.compile("ROLLBACK\\s*(to)*\\s*(\\w+\\d+_*)*"); //$NON-NLS-1$
+ private static Pattern cursorSelectPattern = Pattern.compile("DECLARE \"(\\w+)\" CURSOR(\\s(WITH HOLD|SCROLL))? FOR (.*)", Pattern.CASE_INSENSITIVE|Pattern.DOTALL); //$NON-NLS-1$
+ private static Pattern fetchPattern = Pattern.compile("FETCH (\\d+) IN \"(\\w+)\".*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern movePattern = Pattern.compile("MOVE (\\d+) IN \"(\\w+)\".*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern closePattern = Pattern.compile("CLOSE \"(\\w+)\"", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern deallocatePattern = Pattern.compile("DEALLOCATE \"(\\w+\\d+_*)\"", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern releasePattern = Pattern.compile("RELEASE (\\w+\\d?_*)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern savepointPattern = Pattern.compile("SAVEPOINT (\\w+\\d?_*)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern rollbackPattern = Pattern.compile("ROLLBACK\\s*(to)*\\s*(\\w+\\d+_*)*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+
+
private TeiidDriver driver;
private ODBCClientRemote client;
private Properties props;
@@ -151,6 +164,7 @@
// TODO: this is unbounded map; need to define some boundaries as to how many stmts each session can have
private Map<String, Prepared> preparedMap = Collections.synchronizedMap(new HashMap<String, Prepared>());
private Map<String, Portal> portalMap = Collections.synchronizedMap(new HashMap<String, Portal>());
+ private Map<String, Cursor> cursorMap = Collections.synchronizedMap(new HashMap<String, Cursor>());
public ODBCServerRemoteImpl(ODBCClientInstance client, AuthenticationType authType, TeiidDriver driver) {
this.driver = driver;
@@ -196,6 +210,173 @@
}
}
+ private void cursorExecute(final String cursorName, final String sql, final ResultsFuture<Integer> completion) {
+ if (this.connection != null) {
+ if (sql != null) {
+ try {
+ // close if the name is already used or the unnamed prepare; otherwise
+ // stmt is alive until session ends.
+ Prepared previous = this.preparedMap.remove(cursorName);
+ if (previous != null) {
+ previous.stmt.close();
+ }
+
+ final PreparedStatementImpl stmt = this.connection.prepareStatement(sql);
+ this.executionFuture = stmt.submitExecute();
+ this.executionFuture.addCompletionListener(new ResultsFuture.CompletionListener<Boolean>() {
+ @Override
+ public void onCompletion(ResultsFuture<Boolean> future) {
+ executionFuture = null;
+ try {
+ if (future.get()) {
+ List<PgColInfo> cols = getPgColInfo(stmt.getResultSet().getMetaData());
+ cursorMap.put(cursorName, new Cursor(cursorName, sql, stmt, null, stmt.getResultSet(), cols));
+ client.sendCommandComplete("DECLARE CURSOR", 0); //$NON-NLS-1$
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("execution_failed")); //$NON-NLS-1$
+ }
+ } catch (Throwable e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ });
+ } catch (SQLException e) {
+ errorOccurred(e);
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("no_active_connection")); //$NON-NLS-1$
+ completion.getResultsReceiver().receiveResults(1);
+ }
+
+ }
+
+ private void cursorFetch(String cursorName, int rows, final ResultsFuture<Integer> completion) {
+ Cursor cursor = this.cursorMap.get(cursorName);
+ if (cursor != null) {
+ cursor.fetchSize = rows;
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ this.client.sendCursorResults(cursor.rs, cursor.columnMetadata, result, rows);
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ int rowsSent = 0;
+ try {
+ rowsSent = future.get();
+ client.sendCommandComplete("FETCH", rowsSent); //$NON-NLS-1$
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(rowsSent);
+ };
+ });
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("not_bound", cursorName)); //$NON-NLS-1$
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+
+ private void cursorMove(String prepareName, int rows, final ResultsFuture<Integer> completion) {
+
+ // win odbc driver sending a move after close; and error is ending up in failure; since the below
+ // is not harmful it is ok to send empty move.
+ if (rows == 0) {
+ try {
+ client.sendCommandComplete("MOVE", 0); //$NON-NLS-1$
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(0);
+ return;
+ }
+
+ Cursor cursor = this.cursorMap.get(prepareName);
+ if (cursor != null) {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ this.client.sendMoveCursor(cursor.rs, rows, result);
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ int rowsMoved = 0;
+ try {
+ rowsMoved = future.get();
+ client.sendCommandComplete("MOVE", rowsMoved); //$NON-NLS-1$
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ completion.getResultsReceiver().receiveResults(rowsMoved);
+ };
+ });
+ }
+ else {
+ errorOccurred(RuntimePlugin.Util.getString("not_bound", prepareName)); //$NON-NLS-1$
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+
+ private void cursorClose(String prepareName) throws SQLException, IOException {
+ Cursor cursor = this.cursorMap.remove(prepareName);
+ if (cursor != null) {
+ cursor.rs.close();
+ cursor.stmt.close();
+ this.client.sendCommandComplete("CLOSE CURSOR", 0); //$NON-NLS-1$
+ }
+ }
+
+ private void sqlExecute(final String sql, final ResultsFuture<Integer> completion) throws SQLException {
+ String modfiedSQL = fixSQL(sql);
+ final StatementImpl stmt = connection.createStatement();
+ executionFuture = stmt.submitExecute(modfiedSQL);
+ executionFuture.addCompletionListener(new ResultsFuture.CompletionListener<Boolean>() {
+ @Override
+ public void onCompletion(ResultsFuture<Boolean> future) {
+ executionFuture = null;
+ try {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ if (future.get()) {
+ if (stmt.getResultSet() != null) {
+ List<PgColInfo> cols = getPgColInfo(stmt.getResultSet().getMetaData());
+ client.sendResults(sql, stmt.getResultSet(), cols, result, true);
+ }
+ else {
+ // handles the "SET" commands.
+ client.sendUpdateCount(sql, 0);
+ result.getResultsReceiver().receiveResults(1);
+ }
+ } else {
+ client.sendUpdateCount(sql, stmt.getUpdateCount());
+ setEncoding();
+ result.getResultsReceiver().receiveResults(1);
+ }
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ LogManager.logDetail(LogConstants.CTX_ODBC, e, "Error closing statement"); //$NON-NLS-1$
+ }
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ });
+ } catch (Throwable e) {
+ errorOccurred(e);
+ completion.getResultsReceiver().receiveResults(1);
+ }
+ }
+ });
+ }
+
@Override
public void prepare(String prepareName, String sql, int[] paramType) {
if (this.connection != null) {
@@ -274,60 +455,96 @@
bindName = UNNAMED;
}
+ // special case cursor execution through portal
+ final Cursor cursor = this.cursorMap.get(bindName);
+ if (cursor != null) {
+ sendCursorResults(cursor);
+ return;
+ }
+
final Portal query = this.portalMap.get(bindName);
if (query == null) {
errorOccurred(RuntimePlugin.Util.getString("not_bound", bindName)); //$NON-NLS-1$
- }
- else {
- if (query.sql.trim().isEmpty()) {
- this.client.emptyQueryReceived();
- return;
- }
-
- final PreparedStatementImpl stmt = query.stmt;
- try {
- // maxRows = 0, means unlimited.
- if (maxRows != 0) {
- stmt.setMaxRows(maxRows);
- }
-
- this.executionFuture = stmt.submitExecute();
- executionFuture.addCompletionListener(new ResultsFuture.CompletionListener<Boolean>() {
- @Override
- public void onCompletion(ResultsFuture<Boolean> future) {
- executionFuture = null;
- try {
- ResultsFuture<Void> result = null;
- if (future.get()) {
- result = new ResultsFuture<Void>();
- client.sendResults(query.sql, stmt.getResultSet(), result, true);
- } else {
- result = ResultsFuture.NULL_FUTURE;
- client.sendUpdateCount(query.sql, stmt.getUpdateCount());
- setEncoding();
- }
- result.addCompletionListener(new ResultsFuture.CompletionListener<Void>() {
- public void onCompletion(ResultsFuture<Void> future) {
- try {
- future.get();
- doneExecuting();
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- } catch (ExecutionException e) {
- errorOccurred(e.getCause());
- }
- };
- });
- } catch (Throwable e) {
- errorOccurred(e);
- }
- }
- });
- } catch (SQLException e) {
- errorOccurred(e);
- }
+ return;
+ }
+
+ if (query.sql.trim().isEmpty()) {
+ this.client.emptyQueryReceived();
+ return;
}
+
+ sendPortalResults(maxRows, query);
}
+
+ private void sendPortalResults(int maxRows, final Portal query) {
+ final PreparedStatementImpl stmt = query.stmt;
+ try {
+ // maxRows = 0, means unlimited.
+ if (maxRows != 0) {
+ stmt.setMaxRows(maxRows);
+ }
+
+ this.executionFuture = stmt.submitExecute();
+ executionFuture.addCompletionListener(new ResultsFuture.CompletionListener<Boolean>() {
+ @Override
+ public void onCompletion(ResultsFuture<Boolean> future) {
+ executionFuture = null;
+ try {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ if (future.get()) {
+ List<PgColInfo> cols = getPgColInfo(stmt.getResultSet().getMetaData());
+ client.sendResults(query.sql, stmt.getResultSet(), cols, result, true);
+ } else {
+ // null future
+ client.sendUpdateCount(query.sql, stmt.getUpdateCount());
+ setEncoding();
+ result.getResultsReceiver().receiveResults(1);
+ }
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ future.get();
+ doneExecuting();
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ }
+ };
+ });
+ } catch (Throwable e) {
+ errorOccurred(e);
+ }
+ }
+ });
+ } catch (SQLException e) {
+ errorOccurred(e);
+ }
+ }
+
+ private void sendCursorResults(final Cursor cursor) {
+ ResultsFuture<Integer> result = new ResultsFuture<Integer>();
+ this.client.sendPortalResults(cursor.sql, cursor.rs, cursor.columnMetadata, result, cursor.fetchSize, true);
+ result.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ int rowsSent = future.get();
+ if (rowsSent < cursor.fetchSize) {
+ client.sendCommandComplete(cursor.sql, 0);
+ }
+ else {
+ client.sendPortalSuspended();
+ }
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (ExecutionException e) {
+ errorOccurred(e.getCause());
+ } catch (IOException e) {
+ errorOccurred(e);
+ }
+ };
+ });
+ }
private String fixSQL(String sql) {
String modified = modifySQL(sql);
@@ -409,16 +626,6 @@
}
else if ((m = rollbackPattern.matcher(modified)).matches()) {
return "ROLLBACK"; //$NON-NLS-1$
- }
- else if ((m = savepointPattern.matcher(modified)).matches()) {
- return "SELECT 'SAVEPOINT'"; //$NON-NLS-1$
- }
- else if ((m = releasePattern.matcher(modified)).matches()) {
- return "SELECT 'RELEASE'"; //$NON-NLS-1$
- }
- else if ((m = deallocatePattern.matcher(modified)).matches()) {
- closePreparedStatement(m.group(1));
- return "SELECT 'DEALLOCATE'"; //$NON-NLS-1$
}
}
modified = sql;
@@ -431,7 +638,7 @@
@Override
public void executeQuery(final String query) {
if (beginExecution()) {
- this.client.errorOccurred("Awaiting asynch result"); //$NON-NLS-1$
+ errorOccurred("Awaiting asynch result"); //$NON-NLS-1$
ready();
return;
}
@@ -482,7 +689,8 @@
// followed by a RowDescription message describing the rows that will be returned when the statement
// is eventually executed (or a NoData message if the statement will not return rows).
- this.client.sendResultSetDescription(query.stmt.getMetaData(), query.stmt);
+ List<PgColInfo> cols = getPgColInfo(query.stmt.getMetaData());
+ this.client.sendResultSetDescription(cols);
} catch (SQLException e) {
errorOccurred(e);
}
@@ -516,7 +724,8 @@
}
else {
try {
- this.client.sendResultSetDescription(query.stmt.getMetaData(), query.stmt);
+ List<PgColInfo> cols = getPgColInfo(query.stmt.getMetaData());
+ this.client.sendResultSetDescription(cols);
} catch (SQLException e) {
errorOccurred(e);
}
@@ -622,6 +831,9 @@
try {
if (this.connection != null) {
+ if (!this.connection.getAutoCommit()) {
+ this.connection.rollback(false);
+ }
this.connection.close();
}
} catch (SQLException e) {
@@ -663,90 +875,124 @@
private final class QueryWorkItem implements Runnable {
private final ScriptReader reader;
- String modfiedSQL;
String sql;
private QueryWorkItem(String query) {
- this.reader = new ScriptReader(new StringReader(query));
+ this.reader = new ScriptReader(new StringReader(query));
}
@Override
public void run() {
try {
- if (modfiedSQL == null) {
+ if (sql == null) {
sql = reader.readStatement();
- modfiedSQL = fixSQL(sql);
}
- while (modfiedSQL != null) {
+ while (sql != null) {
try {
- final StatementImpl stmt = connection.createStatement();
- executionFuture = stmt.submitExecute(modfiedSQL);
- executionFuture.addCompletionListener(new ResultsFuture.CompletionListener<Boolean>() {
- @Override
- public void onCompletion(ResultsFuture<Boolean> future) {
- executionFuture = null;
- try {
- ResultsFuture<Void> result = null;
- if (future.get()) {
- if (stmt.getResultSet() != null) {
- result = new ResultsFuture<Void>();
- client.sendResults(sql, stmt.getResultSet(), result, true);
- }
- else {
- // handles the "SET" commands.
- result = ResultsFuture.NULL_FUTURE;
- client.sendUpdateCount(sql, 0);
- }
- } else {
- result = ResultsFuture.NULL_FUTURE;
- client.sendUpdateCount(sql, stmt.getUpdateCount());
- setEncoding();
- }
- result.addCompletionListener(new ResultsFuture.CompletionListener<Void>() {
- public void onCompletion(ResultsFuture<Void> future) {
- try {
- future.get();
- sql = reader.readStatement();
- modfiedSQL = fixSQL(sql);
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- } catch (IOException e) {
- client.errorOccurred(e);
- return;
- } catch (ExecutionException e) {
- client.errorOccurred(e.getCause());
- return;
- } finally {
- try {
- stmt.close();
- } catch (SQLException e) {
- LogManager.logDetail(LogConstants.CTX_ODBC, e, "Error closing statement"); //$NON-NLS-1$
- }
- }
- QueryWorkItem.this.run(); //continue processing
- };
- });
- } catch (Throwable e) {
- client.errorOccurred(e);
- return;
- }
- }
- });
+
+ ResultsFuture<Integer> results = new ResultsFuture<Integer>();
+ results.addCompletionListener(new ResultsFuture.CompletionListener<Integer>() {
+ public void onCompletion(ResultsFuture<Integer> future) {
+ try {
+ future.get();
+ sql = reader.readStatement();
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ } catch (IOException e) {
+ client.errorOccurred(e);
+ return;
+ } catch (ExecutionException e) {
+ client.errorOccurred(e.getCause());
+ return;
+ }
+ QueryWorkItem.this.run(); //continue processing
+ };
+ });
+
+ if (isErrorOccurred()) {
+ if (!connection.getAutoCommit()) {
+ connection.rollback(false);
+ }
+ break;
+ }
+
+ Matcher m = null;
+ if ((m = cursorSelectPattern.matcher(sql)).matches()){
+ cursorExecute(m.group(1), fixSQL(m.group(4)), results);
+ }
+ else if ((m = fetchPattern.matcher(sql)).matches()){
+ cursorFetch(m.group(2), Integer.parseInt(m.group(1)), results);
+ }
+ else if ((m = movePattern.matcher(sql)).matches()){
+ cursorMove(m.group(2), Integer.parseInt(m.group(1)), results);
+ }
+ else if ((m = closePattern.matcher(sql)).matches()){
+ cursorClose(m.group(1));
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else if ((m = savepointPattern.matcher(sql)).matches()) {
+ client.sendCommandComplete("SAVEPOINT", 0); //$NON-NLS-1$
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else if ((m = releasePattern.matcher(sql)).matches()) {
+ client.sendCommandComplete("RELEASE", 0); //$NON-NLS-1$
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else if ((m = deallocatePattern.matcher(sql)).matches()) {
+ closePreparedStatement(m.group(1));
+ client.sendCommandComplete("DEALLOCATE", 0); //$NON-NLS-1$
+ results.getResultsReceiver().receiveResults(1);
+ }
+ else {
+ sqlExecute(sql, results);
+ }
return; //wait for the execution to finish
} catch (SQLException e) {
- client.errorOccurred(e);
+ errorOccurred(e);
break;
}
}
} catch(IOException e) {
- client.errorOccurred(e);
+ errorOccurred(e);
}
doneExecuting();
ready();
}
-
}
-
+
+ private List<PgColInfo> getPgColInfo(ResultSetMetaData meta)
+ throws SQLException {
+ int columns = meta.getColumnCount();
+ final ArrayList<PgColInfo> result = new ArrayList<PgColInfo>(columns);
+ for (int i = 1; i < columns + 1; i++) {
+ final PgColInfo info = new PgColInfo();
+ info.name = meta.getColumnLabel(i).toLowerCase();
+ info.type = meta.getColumnType(i);
+ info.type = convertType(info.type);
+ info.precision = meta.getColumnDisplaySize(i);
+ String name = meta.getColumnName(i);
+ String table = meta.getTableName(i);
+ String schema = meta.getSchemaName(i);
+ if (schema != null) {
+ final PreparedStatementImpl ps = this.connection.prepareStatement("select attrelid, attnum, typoid from matpg_relatt where attname = ? and relname = ? and nspname = ?"); //$NON-NLS-1$
+ ps.setString(1, name);
+ ps.setString(2, table);
+ ps.setString(3, schema);
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) {
+ info.reloid = rs.getInt(1);
+ info.attnum = rs.getShort(2);
+ int specificType = rs.getInt(3);
+ if (!rs.wasNull()) {
+ info.type = specificType;
+ }
+ }
+ }
+ result.add(info);
+ }
+ return result;
+ }
+
/**
* Represents a PostgreSQL Prepared object.
*/
@@ -777,7 +1023,7 @@
/**
* The list of parameter types (if set).
*/
- int[] paramType;
+ int[] paramType;
}
/**
@@ -813,7 +1059,22 @@
/**
* The prepared statement.
*/
- PreparedStatementImpl stmt;
+ PreparedStatementImpl stmt;
}
+
+ static class Cursor extends Prepared {
+ ResultSetImpl rs;
+ int fetchSize = 1000;
+ /**
+ * calculated column metadata
+ */
+ List<PgColInfo> columnMetadata;
+
+ public Cursor (String name, String sql, PreparedStatementImpl stmt, int[] paramType, ResultSetImpl rs, List<PgColInfo> colMetadata) {
+ super(name, sql, stmt, paramType);
+ this.rs = rs;
+ this.columnMetadata = colMetadata;
+ }
+ }
}
Copied: trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java (from rev 3325, branches/7.4.x/runtime/src/main/java/org/teiid/odbc/PGUtil.java)
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java (rev 0)
+++ trunk/runtime/src/main/java/org/teiid/odbc/PGUtil.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.odbc;
+
+import java.sql.Types;
+
+import org.teiid.deployers.PgCatalogMetadataStore;
+
+public class PGUtil {
+
+ public static final int PG_TYPE_VARCHAR = 1043;
+
+ public static final int PG_TYPE_BOOL = 16;
+ public static final int PG_TYPE_BYTEA = 17;
+ public static final int PG_TYPE_BPCHAR = 1042;
+ public static final int PG_TYPE_INT8 = 20;
+ public static final int PG_TYPE_INT2 = 21;
+ public static final int PG_TYPE_INT4 = 23;
+ public static final int PG_TYPE_TEXT = 25;
+ //private static final int PG_TYPE_OID = 26;
+ public static final int PG_TYPE_FLOAT4 = 700;
+ public static final int PG_TYPE_FLOAT8 = 701;
+ public static final int PG_TYPE_UNKNOWN = 705;
+
+ public static final int PG_TYPE_OIDVECTOR = PgCatalogMetadataStore.PG_TYPE_OIDVECTOR;
+ public static final int PG_TYPE_OIDARRAY = PgCatalogMetadataStore.PG_TYPE_OIDARRAY;
+ public static final int PG_TYPE_CHARARRAY = PgCatalogMetadataStore.PG_TYPE_CHARARRAY;
+ public static final int PG_TYPE_TEXTARRAY = PgCatalogMetadataStore.PG_TYPE_TEXTARRAY;
+
+ public static final int PG_TYPE_DATE = 1082;
+ public static final int PG_TYPE_TIME = 1083;
+ public static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
+ public static final int PG_TYPE_NUMERIC = 1700;
+ //private static final int PG_TYPE_LO = 14939;
+
+ public static class PgColInfo {
+ public String name;
+ public int reloid;
+ public short attnum;
+ public int type;
+ public int precision;
+ }
+
+ /**
+ * Types.ARRAY is not supported
+ */
+ public static int convertType(final int type) {
+ switch (type) {
+ case Types.BIT:
+ case Types.BOOLEAN:
+ return PG_TYPE_BOOL;
+ case Types.VARCHAR:
+ return PG_TYPE_VARCHAR;
+ case Types.CHAR:
+ return PG_TYPE_BPCHAR;
+ case Types.TINYINT:
+ case Types.SMALLINT:
+ return PG_TYPE_INT2;
+ case Types.INTEGER:
+ return PG_TYPE_INT4;
+ case Types.BIGINT:
+ return PG_TYPE_INT8;
+ case Types.NUMERIC:
+ case Types.DECIMAL:
+ return PG_TYPE_NUMERIC;
+ case Types.FLOAT:
+ case Types.REAL:
+ return PG_TYPE_FLOAT4;
+ case Types.DOUBLE:
+ return PG_TYPE_FLOAT8;
+ case Types.TIME:
+ return PG_TYPE_TIME;
+ case Types.DATE:
+ return PG_TYPE_DATE;
+ case Types.TIMESTAMP:
+ return PG_TYPE_TIMESTAMP_NO_TMZONE;
+
+ case Types.BLOB:
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ return PG_TYPE_BYTEA;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ return PG_TYPE_TEXT;
+
+ case Types.SQLXML:
+ return PG_TYPE_TEXT;
+
+ default:
+ return PG_TYPE_UNKNOWN;
+ }
+ }
+}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -21,6 +21,26 @@
* 02110-1301 USA.
*/package org.teiid.transport;
+import static org.teiid.odbc.PGUtil.PG_TYPE_BOOL;
+import static org.teiid.odbc.PGUtil.PG_TYPE_BPCHAR;
+import static org.teiid.odbc.PGUtil.PG_TYPE_BYTEA;
+import static org.teiid.odbc.PGUtil.PG_TYPE_CHARARRAY;
+import static org.teiid.odbc.PGUtil.PG_TYPE_DATE;
+import static org.teiid.odbc.PGUtil.PG_TYPE_FLOAT4;
+import static org.teiid.odbc.PGUtil.PG_TYPE_FLOAT8;
+import static org.teiid.odbc.PGUtil.PG_TYPE_INT2;
+import static org.teiid.odbc.PGUtil.PG_TYPE_INT4;
+import static org.teiid.odbc.PGUtil.PG_TYPE_INT8;
+import static org.teiid.odbc.PGUtil.PG_TYPE_NUMERIC;
+import static org.teiid.odbc.PGUtil.PG_TYPE_OIDARRAY;
+import static org.teiid.odbc.PGUtil.PG_TYPE_OIDVECTOR;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TEXT;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TEXTARRAY;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TIME;
+import static org.teiid.odbc.PGUtil.PG_TYPE_TIMESTAMP_NO_TMZONE;
+import static org.teiid.odbc.PGUtil.PG_TYPE_UNKNOWN;
+import static org.teiid.odbc.PGUtil.PG_TYPE_VARCHAR;
+
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -32,13 +52,9 @@
import java.sql.Blob;
import java.sql.Clob;
import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
import java.sql.SQLException;
-import java.sql.Statement;
import java.sql.Types;
-import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@@ -58,16 +74,15 @@
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.ReflectionHelper;
-import org.teiid.deployers.PgCatalogMetadataStore;
import org.teiid.jdbc.ResultSetImpl;
import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.net.socket.ServiceInvocationStruct;
import org.teiid.odbc.ODBCClientRemote;
+import org.teiid.odbc.PGUtil.PgColInfo;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.transport.pg.PGbytea;
-
/**
* Represents the messages going from Server --> PG ODBC Client
* Some parts of this code is taken from H2's implementation of ODBC
@@ -92,19 +107,24 @@
}
}
}
-
+
+ // 300k
+ static int ODBC_SOCKET_BUFF_SIZE = Integer.parseInt(System.getProperty("ODBCPacketSize", "307200"));
+
private final class ResultsWorkItem implements Runnable {
private final List<PgColInfo> cols;
- private final String sql;
private final ResultSetImpl rs;
- private final ResultsFuture<Void> result;
+ private final ResultsFuture<Integer> result;
+ private int rows2Send;
+ private int rowsSent = 0;
+ private int rowsInBuffer = 0;
+ private ChannelBuffer buffer = ChannelBuffers.directBuffer(ODBC_SOCKET_BUFF_SIZE);
- private ResultsWorkItem(List<PgColInfo> cols, String sql,
- ResultSetImpl rs, ResultsFuture<Void> result) {
+ private ResultsWorkItem(List<PgColInfo> cols, ResultSetImpl rs, ResultsFuture<Integer> result, int rows2Send) {
this.cols = cols;
- this.sql = sql;
this.rs = rs;
this.result = result;
+ this.rows2Send = rows2Send;
}
@Override
@@ -117,8 +137,10 @@
@Override
public void onCompletion(ResultsFuture<Boolean> future) {
if (processRow(future)) {
- //this can be recursive, but ideally won't be called many times
- ResultsWorkItem.this.run();
+ if (rowsSent != rows2Send) {
+ //this can be recursive, but ideally won't be called many times
+ ResultsWorkItem.this.run();
+ }
}
}
});
@@ -138,10 +160,18 @@
boolean processNext = true;
try {
if (future.get()) {
- sendDataRow(rs, cols);
+ sendDataRow(rs, cols, buffer);
+ rowsSent++;
+ rowsInBuffer++;
+ boolean done = rowsSent == rows2Send;
+ flushResults(done);
+ processNext = !done;
+ if (done) {
+ result.getResultsReceiver().receiveResults(rowsSent);
+ }
} else {
- sendCommandComplete(sql, 0);
- result.getResultsReceiver().receiveResults(null);
+ sendContents(buffer);
+ result.getResultsReceiver().receiveResults(rowsSent);
processNext = false;
}
} catch (Throwable t) {
@@ -150,33 +180,17 @@
}
return processNext;
}
+
+ private void flushResults(boolean force) {
+ int avgRowsize = buffer.readableBytes()/rowsInBuffer;
+ if (force || buffer.writableBytes() < (avgRowsize*2)) {
+ sendContents(buffer);
+ buffer= ChannelBuffers.directBuffer(ODBC_SOCKET_BUFF_SIZE);
+ rowsInBuffer = 0;
+ }
+ }
}
-
- private static final int PG_TYPE_VARCHAR = 1043;
-
- private static final int PG_TYPE_BOOL = 16;
- private static final int PG_TYPE_BYTEA = 17;
- private static final int PG_TYPE_BPCHAR = 1042;
- private static final int PG_TYPE_INT8 = 20;
- private static final int PG_TYPE_INT2 = 21;
- private static final int PG_TYPE_INT4 = 23;
- private static final int PG_TYPE_TEXT = 25;
- //private static final int PG_TYPE_OID = 26;
- private static final int PG_TYPE_FLOAT4 = 700;
- private static final int PG_TYPE_FLOAT8 = 701;
- private static final int PG_TYPE_UNKNOWN = 705;
- private static final int PG_TYPE_OIDVECTOR = PgCatalogMetadataStore.PG_TYPE_OIDVECTOR;
- private static final int PG_TYPE_OIDARRAY = PgCatalogMetadataStore.PG_TYPE_OIDARRAY;
- private static final int PG_TYPE_CHARARRAY = PgCatalogMetadataStore.PG_TYPE_CHARARRAY;
- private static final int PG_TYPE_TEXTARRAY = PgCatalogMetadataStore.PG_TYPE_TEXTARRAY;
-
- private static final int PG_TYPE_DATE = 1082;
- private static final int PG_TYPE_TIME = 1083;
- private static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
- private static final int PG_TYPE_NUMERIC = 1700;
- //private static final int PG_TYPE_LO = 14939;
-
private DataOutputStream dataOut;
private ByteArrayOutputStream outBuffer;
private char messageType;
@@ -191,7 +205,7 @@
private SSLConfiguration config;
- public PgBackendProtocol(int maxLobSize, SSLConfiguration config) {
+ public PgBackendProtocol(int maxLobSize, SSLConfiguration config) {
this.maxLobSize = maxLobSize;
this.config = config;
}
@@ -340,35 +354,65 @@
}
@Override
- public void sendResultSetDescription(ResultSetMetaData metaData, Statement stmt) {
+ public void sendResultSetDescription(List<PgColInfo> cols) {
try {
+ sendRowDescription(cols);
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void sendCursorResults(ResultSetImpl rs, List<PgColInfo> cols, ResultsFuture<Integer> result, int rowCount) {
+ try {
+ sendRowDescription(cols);
+
+ ResultsWorkItem r = new ResultsWorkItem(cols, rs, result, rowCount);
+ r.run();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void sendPortalResults(String sql, ResultSetImpl rs, List<PgColInfo> cols, ResultsFuture<Integer> result, int rowCount, boolean portal) {
+ ResultsWorkItem r = new ResultsWorkItem(cols, rs, result, rowCount);
+ r.run();
+ }
+
+ @Override
+ public void sendMoveCursor(ResultSetImpl rs, int rowCount, ResultsFuture<Integer> results) {
+ try {
try {
- List<PgColInfo> cols = getPgColInfo(metaData, stmt);
- sendRowDescription(cols);
+ int rowsMoved = 0;
+ for (int i = 0; i < rowCount; i++) {
+ if (!rs.next()) {
+ break;
+ }
+ rowsMoved++;
+ }
+ results.getResultsReceiver().receiveResults(rowsMoved);
} catch (SQLException e) {
- sendErrorResponse(e);
- }
+ sendErrorResponse(e);
+ }
} catch (IOException e) {
terminate(e);
}
- }
+ }
@Override
- public void sendResults(final String sql, final ResultSetImpl rs, ResultsFuture<Void> result, boolean describeRows) {
+ public void sendResults(final String sql, final ResultSetImpl rs, List<PgColInfo> cols, ResultsFuture<Integer> result, boolean describeRows) {
try {
if (nextFuture != null) {
sendErrorResponse(new IllegalStateException("Pending results have not been sent")); //$NON-NLS-1$
}
- ResultSetMetaData meta = rs.getMetaData();
- List<PgColInfo> cols = getPgColInfo(meta, rs.getStatement());
if (describeRows) {
sendRowDescription(cols);
}
- Runnable r = new ResultsWorkItem(cols, sql, rs, result);
+ ResultsWorkItem r = new ResultsWorkItem(cols, rs, result, -1);
r.run();
- } catch (SQLException e) {
- result.getResultsReceiver().exceptionOccurred(e);
+ sendCommandComplete(sql, 0);
} catch (IOException e) {
terminate(e);
}
@@ -425,8 +469,9 @@
startMessage('I');
sendMessage();
}
-
- private void sendCommandComplete(String sql, int updateCount) throws IOException {
+
+ @Override
+ public void sendCommandComplete(String sql, int updateCount) throws IOException {
startMessage('C');
sql = sql.trim().toUpperCase();
// TODO remove remarks at the beginning
@@ -439,7 +484,7 @@
tag = "UPDATE " + updateCount;
} else if (sql.startsWith("SELECT") || sql.startsWith("CALL")) {
tag = "SELECT";
- } else if (sql.startsWith("BEGIN")) {
+ } else if (sql.startsWith("BEGIN") || sql.startsWith("START TRANSACTION")) {
tag = "BEGIN";
} else if (sql.startsWith("COMMIT")) {
tag = "COMMIT";
@@ -447,15 +492,23 @@
tag = "ROLLBACK";
} else if (sql.startsWith("SET ")) {
tag = "SET";
- }else {
- trace("Check command tag:", sql);
- tag = "UPDATE " + updateCount;
+ } else if (sql.startsWith("DECLARE CURSOR")) {
+ tag = "DECLARE CURSOR";
+ } else if (sql.startsWith("CLOSE CURSOR")) {
+ tag = "CLOSE CURSOR";
+ } else if (sql.startsWith("FETCH")) {
+ tag = "FETCH "+ updateCount;
+ } else if (sql.startsWith("MOVE")) {
+ tag = "MOVE "+ updateCount;
}
+ else {
+ tag = sql;
+ }
writeString(tag);
sendMessage();
}
- private void sendDataRow(ResultSet rs, List<PgColInfo> cols) throws SQLException, IOException {
+ private void sendDataRow(ResultSet rs, List<PgColInfo> cols, ChannelBuffer buffer) throws SQLException, IOException {
startMessage('D');
writeShort(cols.size());
for (int i = 0; i < cols.size(); i++) {
@@ -467,9 +520,18 @@
write(bytes);
}
}
- sendMessage();
+
+ byte[] buff = outBuffer.toByteArray();
+ int len = buff.length;
+ this.outBuffer = null;
+ this.dataOut = null;
+
+ // now build the wire contents.
+ buffer.writeByte((byte)this.messageType);
+ buffer.writeInt(len+4);
+ buffer.writeBytes(buff);
}
-
+
private byte[] getContent(ResultSet rs, PgColInfo col, int column) throws SQLException, TeiidSQLException, IOException {
byte[] bytes = null;
switch (col.type) {
@@ -612,20 +674,7 @@
write(0);
sendMessage();
}
-
- private void sendNoData() {
- startMessage('n');
- sendMessage();
- }
- private static class PgColInfo {
- String name;
- int reloid;
- short attnum;
- int type;
- int precision;
- }
-
private void sendRowDescription(List<PgColInfo> cols) throws IOException {
startMessage('T');
writeShort(cols.size());
@@ -647,46 +696,6 @@
sendMessage();
}
- private List<PgColInfo> getPgColInfo(ResultSetMetaData meta, Statement stmt)
- throws SQLException {
- int columns = meta.getColumnCount();
- ArrayList<PgColInfo> result = new ArrayList<PgColInfo>(columns);
- for (int i = 1; i < columns + 1; i++) {
- PgColInfo info = new PgColInfo();
- info.name = meta.getColumnName(i).toLowerCase();
- info.type = meta.getColumnType(i);
- info.type = convertType(info.type);
- info.precision = meta.getColumnDisplaySize(i);
- String name = meta.getColumnName(i);
- String table = meta.getTableName(i);
- String schema = meta.getSchemaName(i);
- if (schema != null) {
- PreparedStatement ps = null;
- try {
- ps = stmt.getConnection().prepareStatement("select attrelid, attnum, typoid from matpg_relatt where attname = ? and relname = ? and nspname = ?");
- ps.setString(1, name);
- ps.setString(2, table);
- ps.setString(3, schema);
- ResultSet rs = ps.executeQuery();
- if (rs.next()) {
- info.reloid = rs.getInt(1);
- info.attnum = rs.getShort(2);
- int specificType = rs.getInt(3);
- if (!rs.wasNull()) {
- info.type = specificType;
- }
- }
- } finally {
- if (ps != null) {
- ps.close();
- }
- }
- }
- result.add(info);
- }
- return result;
- }
-
private int getTypeSize(int pgType, int precision) {
switch (pgType) {
case PG_TYPE_VARCHAR:
@@ -728,6 +737,12 @@
startMessage('2');
sendMessage();
}
+
+ @Override
+ public void sendPortalSuspended() {
+ startMessage('s');
+ sendMessage();
+ }
private void sendAuthenticationCleartextPassword() throws IOException {
startMessage('R');
@@ -844,6 +859,10 @@
buffer.writeBytes(buff);
Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());
}
+
+ private void sendContents(ChannelBuffer buffer) {
+ Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());
+ }
private static void trace(String... msg) {
LogManager.logTrace(LogConstants.CTX_ODBC, (Object[])msg);
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-07-22 16:26:08 UTC (rev 3327)
@@ -92,5 +92,6 @@
ambigious_name=Ambiguous VDB name specified. Only single occurrence of the "." is allowed in the VDB name. Also, when version based vdb name is specified, then a separate "version" connection option is not allowed:{0}.{1}
lo_not_supported=LO functions are not supported
SSLConfiguration.no_anonymous=The anonymous cipher suite TLS_DH_anon_WITH_AES_128_CBC_SHA is not available. Please change the transport to be non-SSL or use non-anonymous SSL.
+execution_failed=Cursor execution failed
PgBackendProtocol.ssl_error=Could not initialize ODBC SSL. non-SSL connections will still be allowed.
\ No newline at end of file
Modified: trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -26,24 +26,39 @@
import java.lang.Thread.UncaughtExceptionHandler;
import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
-import java.util.LinkedHashMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
-import org.jboss.netty.handler.timeout.TimeoutException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.dqp.internal.datamgr.ConnectorManager;
+import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
+import org.teiid.language.Command;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.FunctionParameter;
-import org.teiid.metadata.MetadataStore;
-import org.teiid.metadata.Schema;
+import org.teiid.metadata.RuntimeMetadata;
import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.function.metadata.FunctionCategoryConstants;
-import org.teiid.query.metadata.TransformationMetadata.Resource;
+import org.teiid.translator.DataNotAvailableException;
+import org.teiid.translator.Execution;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ExecutionFactory;
+import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.TranslatorException;
@SuppressWarnings("nls")
public class TestLocalConnections {
@@ -62,12 +77,14 @@
static Condition waiting = lock.newCondition();
static Condition wait = lock.newCondition();
+ static Semaphore sourceCounter = new Semaphore(0);
+
public static int blocking() throws InterruptedException {
lock.lock();
try {
waiting.signal();
if (!wait.await(2, TimeUnit.SECONDS)) {
- throw new TimeoutException();
+ throw new RuntimeException();
}
} finally {
lock.unlock();
@@ -77,15 +94,75 @@
static FakeServer server = new FakeServer();
- @BeforeClass public static void oneTimeSetup() {
+ @SuppressWarnings("serial")
+ @BeforeClass public static void oneTimeSetup() throws Exception {
server.setUseCallingThread(true);
- MetadataStore ms = new MetadataStore();
- Schema s = new Schema();
- s.setName("test");
+ server.setConnectorManagerRepository(new ConnectorManagerRepository() {
+ @Override
+ public ConnectorManager getConnectorManager(String connectorName) {
+ return new ConnectorManager(connectorName, connectorName) {
+ @Override
+ protected ExecutionFactory<Object, Object> getExecutionFactory() {
+ return new ExecutionFactory<Object, Object>() {
+ @Override
+ public Execution createExecution(Command command,
+ ExecutionContext executionContext,
+ RuntimeMetadata metadata, Object connection)
+ throws TranslatorException {
+ return new ResultSetExecution() {
+
+ boolean returnedRow = false;
+
+ @Override
+ public void execute() throws TranslatorException {
+ lock.lock();
+ try {
+ sourceCounter.release();
+ if (!wait.await(2, TimeUnit.SECONDS)) {
+ throw new RuntimeException();
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public void cancel() throws TranslatorException {
+
+ }
+
+ @Override
+ public List<?> next() throws TranslatorException, DataNotAvailableException {
+ if (returnedRow) {
+ return null;
+ }
+ returnedRow = true;
+ return new ArrayList<Object>(Collections.singleton(null));
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ protected Object getConnectionFactory()
+ throws TranslatorException {
+ return null;
+ }
+ };
+ }
+ });
FunctionMethod function = new FunctionMethod("foo", null, FunctionCategoryConstants.MISCELLANEOUS, PushDown.CANNOT_PUSHDOWN, TestLocalConnections.class.getName(), "blocking", new FunctionParameter[0], new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER), true, FunctionMethod.Determinism.NONDETERMINISTIC);
- s.addFunction(function);
- ms.addSchema(s);
- server.deployVDB("test", ms, new LinkedHashMap<String, Resource>());
+ HashMap<String, Collection<FunctionMethod>> udfs = new HashMap<String, Collection<FunctionMethod>>();
+ udfs.put("test", Arrays.asList(function));
+ server.deployVDB("test", UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb", udfs);
}
@AfterClass public static void oneTimeTearDown() {
@@ -102,6 +179,7 @@
Statement s = c.createStatement();
s.execute("select foo()");
+ s.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -131,9 +209,129 @@
if (t.isAlive()) {
fail();
}
+ s.close();
if (handler.t != null) {
throw handler.t;
}
}
+ @Test public void testUseInDifferentThreads() throws Throwable {
+ Connection c = server.createConnection("jdbc:teiid:test");
+
+ final Statement s = c.createStatement();
+ s.execute("select 1");
+
+ assertFalse(server.dqp.getRequests().isEmpty());
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ s.close();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+ t.start();
+ t.join(2000);
+ if (t.isAlive()) {
+ fail();
+ }
+
+ assertTrue(server.dqp.getRequests().isEmpty());
+
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
+ @Test public void testWait() throws Throwable {
+ final Connection c = server.createConnection("jdbc:teiid:test");
+
+ Thread t = new Thread() {
+ public void run() {
+ Statement s;
+ try {
+ s = c.createStatement();
+ assertTrue(s.execute("select part_id from parts"));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ t.start();
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+
+ sourceCounter.acquire();
+
+ //t should now be waiting also
+
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+
+ //t should finish
+ t.join();
+
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
+ @Test public void testWaitMultiple() throws Throwable {
+ final Connection c = server.createConnection("jdbc:teiid:test");
+
+ Thread t = new Thread() {
+ public void run() {
+ Statement s;
+ try {
+ s = c.createStatement();
+ assertTrue(s.execute("select part_id from parts union all select part_id from parts"));
+ ResultSet r = s.getResultSet();
+
+ //wake up the other source thread, should put the requestworkitem into the more work state
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+ Thread.sleep(1000); //TODO: need a better hook to determine that connector work has finished
+ while (r.next()) {
+ //will hang unless this thread is allowed to resume processing
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ t.start();
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+
+ sourceCounter.acquire(2);
+
+ //t should now be waiting also
+
+ //wake up 1 source thread
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+
+ t.join();
+
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
}
Modified: trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestMMDatabaseMetaData.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -615,6 +615,12 @@
ResultSet rs = dbmd.getTables(null, "SYSTEM", "VIRTUALDATABASES", null); //$NON-NLS-1$ //$NON-NLS-2$
compareResultSet(rs);
}
+
+ @Test
+ public void testGetTables_noTypes() throws Exception {
+ ResultSet rs = dbmd.getTables(null, "SYSTEM", "VIRTUALDATABASES", new String[0]); //$NON-NLS-1$ //$NON-NLS-2$
+ assertFalse(rs.next());
+ }
@Test
public void testGetTables_specificTableTypes() throws Exception {
Modified: trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2011-07-22 16:26:08 UTC (rev 3327)
@@ -222,6 +222,12 @@
TestMMDatabaseMetaData.compareResultSet(rs);
}
+ @Test public void testColumnMetadataWithAlias() throws Exception {
+ PreparedStatement stmt = conn.prepareStatement("select ta.attname as x from pg_catalog.pg_attribute ta limit 1");
+ ResultSet rs = stmt.executeQuery();
+ TestMMDatabaseMetaData.compareResultSet(rs);
+ }
+
@Test public void testPreparedError() throws Exception {
PreparedStatement stmt = conn.prepareStatement("select cast(? as integer)");
stmt.setString(1, "a");
@@ -255,6 +261,13 @@
assertEquals("oid", rs.getArray("proargtypes").getBaseTypeName());
}
+ // this does not work as JDBC always sends the queries in prepared form
+ public void testPgDeclareCursor() throws Exception {
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery("begin;declare \"foo\" cursor for select * from pg_proc;fetch 10 in \"foo\"; close \"foo\"");
+ rs.next();
+ }
+
@Test public void testPgProcedure() throws Exception {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select has_function_privilege(100, 'foo')");
Property changes on: trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java:3149-3217
+ /branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java:3149-3217,3281-3325
Added: trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected
===================================================================
--- trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected (rev 0)
+++ trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testColumnMetadataWithAlias.expected 2011-07-22 16:26:08 UTC (rev 3327)
@@ -0,0 +1,6 @@
+varchar
+x
+PART_ID
+Row Count : 1
+getColumnName getColumnType getCatalogName getColumnClassName getColumnLabel getColumnTypeName getSchemaName getTableName getColumnDisplaySize getPrecision getScale isAutoIncrement isCaseSensitive isCurrency isDefinitelyWritable isNullable isReadOnly isSearchable isSigned isWritable
+x 12 java.lang.String x varchar 2147483647 0 0 false true false false 1 false true false true
Modified: trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected
===================================================================
--- trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected 2011-07-22 16:26:08 UTC (rev 3327)
@@ -1,10 +1,10 @@
varchar int2 varchar varchar varchar
-name attnum tablename schemaname tablename
+attname attnum relname nspname relname
oid 1 pg_attribute pg_catalog pg_attribute
Row Count : 1
getColumnName getColumnType getCatalogName getColumnClassName getColumnLabel getColumnTypeName getSchemaName getTableName getColumnDisplaySize getPrecision getScale isAutoIncrement isCaseSensitive isCurrency isDefinitelyWritable isNullable isReadOnly isSearchable isSigned isWritable
-name 12 java.lang.String name varchar 2147483647 0 0 false true false false 0 false true false true
+attname 12 java.lang.String attname varchar 2147483647 0 0 false true false false 0 false true false true
attnum 5 java.lang.Integer attnum int2 6 5 0 false false false false 2 false true true true
-tablename 12 java.lang.String tablename varchar 2147483647 0 0 false true false false 0 false true false true
-schemaname 12 java.lang.String schemaname varchar 2147483647 0 0 false true false false 1 false true false true
-tablename 12 java.lang.String tablename varchar 2147483647 0 0 false true false false 0 false true false true
+relname 12 java.lang.String relname varchar 2147483647 0 0 false true false false 0 false true false true
+nspname 12 java.lang.String nspname varchar 2147483647 0 0 false true false false 1 false true false true
+relname 12 java.lang.String relname varchar 2147483647 0 0 false true false false 0 false true false true
Property changes on: trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/test-integration/common/src/test/resources/TestODBCSocketTransport/testPk.expected:3281-3325
Modified: trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected
===================================================================
--- trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected 2011-07-22 15:32:56 UTC (rev 3326)
+++ trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected 2011-07-22 16:26:08 UTC (rev 3327)
@@ -1,10 +1,10 @@
varchar int2 varchar varchar varchar
-name attnum tablename schemaname tablename
+attname attnum relname nspname relname
oid 1 pg_attribute pg_catalog pg_attribute
Row Count : 1
getColumnName getColumnType getCatalogName getColumnClassName getColumnLabel getColumnTypeName getSchemaName getTableName getColumnDisplaySize getPrecision getScale isAutoIncrement isCaseSensitive isCurrency isDefinitelyWritable isNullable isReadOnly isSearchable isSigned isWritable
-name 12 java.lang.String name varchar 2147483647 0 0 false true false false 0 false true false true
+attname 12 java.lang.String attname varchar 2147483647 0 0 false true false false 0 false true false true
attnum 5 java.lang.Integer attnum int2 6 5 0 false false false false 2 false true true true
-tablename 12 java.lang.String tablename varchar 2147483647 0 0 false true false false 0 false true false true
-schemaname 12 java.lang.String schemaname varchar 2147483647 0 0 false true false false 1 false true false true
-tablename 12 java.lang.String tablename varchar 2147483647 0 0 false true false false 0 false true false true
+relname 12 java.lang.String relname varchar 2147483647 0 0 false true false false 0 false true false true
+nspname 12 java.lang.String nspname varchar 2147483647 0 0 false true false false 1 false true false true
+relname 12 java.lang.String relname varchar 2147483647 0 0 false true false false 0 false true false true
Property changes on: trunk/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected
___________________________________________________________________
Added: svn:mergeinfo
+ /branches/7.4.x/test-integration/common/src/test/resources/TestODBCSocketTransport/testPkPrepared.expected:3281-3325
13 years, 5 months