teiid SVN: r2906 - in trunk/engine/src: main/java/org/teiid/query/optimizer/relational/rules and 3 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-14 15:34:03 -0500 (Mon, 14 Feb 2011)
New Revision: 2906
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestAccessPatterns.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinWithFunction.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestRuleRaiseNull.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
Log:
TEIID-1471 reusing the assign element logic to filter elements prior to optional join removal and merge virtual
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-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -437,6 +437,10 @@
if (hints.hasJoin && hints.hasOptionalJoin) {
rules.push(RuleConstants.REMOVE_OPTIONAL_JOINS);
}
+ if (hints.hasVirtualGroups || (hints.hasJoin && hints.hasOptionalJoin)) {
+ //do initial filtering to make merging and optional join logic easier
+ rules.push(RuleConstants.ASSIGN_OUTPUT_ELEMENTS);
+ }
rules.push(RuleConstants.PLACE_ACCESS);
return rules;
}
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-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -123,15 +123,6 @@
int nodeType = root.getType();
- //fix no output elements if possible
- if(outputElements.isEmpty() && (nodeType == NodeConstants.Types.ACCESS || nodeType == NodeConstants.Types.SOURCE)) {
- PlanNode groupSource = FrameUtil.findJoinSourceNode(root);
- ElementSymbol symbol = selectOutputElement(groupSource.getGroups(), metadata);
- if (symbol != null) {//can be null for procedures
- outputElements.add(symbol);
- }
- }
-
// Update this node's output columns based on parent's columns
root.setProperty(NodeConstants.Info.OUTPUT_COLS, outputElements);
@@ -153,11 +144,21 @@
//add missing sort columns
OrderBy elements = (OrderBy) root.getProperty(NodeConstants.Info.SORT_ORDER);
outputElements = new ArrayList<SingleElementSymbol>(outputElements);
+ boolean hasUnrelated = false;
for (OrderByItem item : elements.getOrderByItems()) {
- if (!outputElements.contains(item.getSymbol())) {
- outputElements.add(item.getSymbol());
+ if (item.getExpressionPosition() == -1) {
+ int index = outputElements.indexOf(item.getSymbol());
+ if (index != -1) {
+ item.setExpressionPosition(index);
+ } else {
+ hasUnrelated = true;
+ outputElements.add(item.getSymbol());
+ }
}
}
+ if (!hasUnrelated) {
+ root.setProperty(NodeConstants.Info.UNRELATED_SORT, false);
+ }
}
assignOutputElements(root.getLastChild(), outputElements, metadata, capFinder, rules, analysisRecord, context);
break;
@@ -165,24 +166,6 @@
outputElements = (List<SingleElementSymbol>)determineSourceOutput(root, outputElements, metadata, capFinder);
root.setProperty(NodeConstants.Info.OUTPUT_COLS, outputElements);
List<SingleElementSymbol> childElements = filterVirtualElements(root, outputElements, metadata);
- SymbolMap symbolMap = (SymbolMap)root.getProperty(NodeConstants.Info.SYMBOL_MAP);
- int size = symbolMap.asMap().size();
- symbolMap.asUpdatableMap().keySet().retainAll(outputElements);
- //if we have removed projected symbols, then we need to update the sort columns
- if (size > outputElements.size()) {
- PlanNode sortNode = NodeEditor.findNodePreOrder(root, NodeConstants.Types.SORT, NodeConstants.Types.PROJECT);
- if (sortNode != null && !sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
- List<Expression> symbolOrder = symbolMap.getValues();
- OrderBy elements = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
- for (OrderByItem item : elements.getOrderByItems()) {
- int position = symbolOrder.indexOf(SymbolMap.getExpression(item.getSymbol()));
- item.setExpressionPosition(position);
- if (position == -1) {
- sortNode.setProperty(NodeConstants.Info.UNRELATED_SORT, true);
- }
- }
- }
- }
assignOutputElements(root.getFirstChild(), childElements, metadata, capFinder, rules, analysisRecord, context);
break;
}
@@ -202,7 +185,29 @@
execute(intoRoot.getFirstChild(), metadata, capFinder, rules, analysisRecord, context);
return;
}
- root.setProperty(NodeConstants.Info.PROJECT_COLS, outputElements);
+ List<SingleElementSymbol> projectCols = outputElements;
+ boolean modifiedProject = false;
+ PlanNode sortNode = NodeEditor.findParent(root, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
+ if (sortNode != null && sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
+ //if this is the initial rule run, remove unrelated order before changing the project cols
+ if (rules.contains(RuleConstants.ASSIGN_OUTPUT_ELEMENTS)) {
+ OrderBy elements = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
+ projectCols = new ArrayList<SingleElementSymbol>(projectCols);
+ for (OrderByItem item : elements.getOrderByItems()) {
+ if (item.getExpressionPosition() == -1) {
+ projectCols.remove(item.getSymbol());
+ }
+ }
+ } else {
+ modifiedProject = true;
+ }
+ }
+ root.setProperty(NodeConstants.Info.PROJECT_COLS, projectCols);
+ if (modifiedProject) {
+ root.getGroups().clear();
+ root.addGroups(GroupsUsedByElementsVisitor.getGroups(projectCols));
+ root.addGroups(GroupsUsedByElementsVisitor.getGroups(root.getCorrelatedReferenceElements()));
+ }
}
List<SingleElementSymbol> requiredInput = collectRequiredInputSymbols(root);
@@ -292,33 +297,6 @@
}
/**
- * Find a selectable element in the specified groups. This is a helper for fixing
- * the "no elements" case.
- *
- * @param groups Bunch of groups
- * @param metadata Metadata implementation
- * @throws QueryPlannerException
- */
- private ElementSymbol selectOutputElement(Collection<GroupSymbol> groups, QueryMetadataInterface metadata)
- throws QueryMetadataException, TeiidComponentException {
-
- // Find a group with selectable elements and pick the first one
- for (GroupSymbol group : groups) {
- List<ElementSymbol> elements = (List<ElementSymbol>)ResolverUtil.resolveElementsInGroup(group, metadata);
-
- for (ElementSymbol element : elements) {
- if(metadata.elementSupports(element.getMetadataID(), SupportConstants.Element.SELECT)) {
- element = (ElementSymbol)element.clone();
- element.setGroupSymbol(group);
- return element;
- }
- }
- }
-
- return null;
- }
-
- /**
* <p>This method looks at a source node, which defines a virtual group, and filters the
* virtual elements defined by the group down into just the output elements needed
* by that source node. This means, for instance, that the PROJECT node at the top
@@ -347,13 +325,29 @@
Arrays.fill(filteredIndex, -1);
SymbolMap symbolMap = (SymbolMap)sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
- List originalOrder = symbolMap.getKeys();
+ List<ElementSymbol> originalOrder = symbolMap.getKeys();
+
+ boolean updateGroups = outputColumns.size() != originalOrder.size();
+ boolean[] seenIndex = new boolean[outputColumns.size()];
+
for (int i = 0; i < outputColumns.size(); i++) {
Expression expr = outputColumns.get(i);
filteredIndex[i] = originalOrder.indexOf(expr);
+ if (!updateGroups) {
+ seenIndex[filteredIndex[i]] = true;
+ }
}
+ if (!updateGroups) {
+ for (boolean b : seenIndex) {
+ if (!b) {
+ updateGroups = true;
+ break;
+ }
+ }
+ }
+
List<SingleElementSymbol> newCols = null;
for(int i=allProjects.size()-1; i>=0; i--) {
PlanNode projectNode = allProjects.get(i);
@@ -365,8 +359,51 @@
}
projectNode.setProperty(NodeConstants.Info.PROJECT_COLS, newCols);
+ if (updateGroups) {
+ projectNode.getGroups().clear();
+ projectNode.addGroups(GroupsUsedByElementsVisitor.getGroups(newCols));
+ projectNode.addGroups(GroupsUsedByElementsVisitor.getGroups(projectNode.getCorrelatedReferenceElements()));
+ }
}
+
+ if (!updateGroups) {
+ for (int i : filteredIndex) {
+ if (i != filteredIndex[i]) {
+ updateGroups = true;
+ break;
+ }
+ }
+ }
+
+ if (updateGroups) {
+ SymbolMap newMap = new SymbolMap();
+ List<Expression> originalExpressionOrder = symbolMap.getValues();
+ for (int i = 0; i < filteredIndex.length; i++) {
+ newMap.addMapping(originalOrder.get(filteredIndex[i]), originalExpressionOrder.get(filteredIndex[i]));
+ }
+ PlanNode sortNode = NodeEditor.findNodePreOrder(sourceNode, NodeConstants.Types.SORT, NodeConstants.Types.PROJECT);
+ if (sortNode != null) {
+ OrderBy elements = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
+ for (OrderByItem item : elements.getOrderByItems()) {
+ if (item.getExpressionPosition() == -1) {
+ continue;
+ }
+ item.setExpressionPosition(-1);
+ for (int i = 0; i < filteredIndex.length; i++) {
+ if (item.getExpressionPosition() == filteredIndex[i]) {
+ item.setExpressionPosition(i);
+ break;
+ }
+ }
+ if (item.getExpressionPosition() == -1) {
+ sortNode.setProperty(NodeConstants.Info.UNRELATED_SORT, true);
+ }
+ }
+ }
+ sourceNode.setProperty(NodeConstants.Info.SYMBOL_MAP, newMap);
+ }
+
// Create output columns for virtual group project
return newCols;
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -23,6 +23,7 @@
package org.teiid.query.optimizer.relational.rules;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
@@ -33,6 +34,7 @@
import org.teiid.core.types.DataTypeManager;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.metadata.SupportConstants;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.optimizer.relational.OptimizerRule;
@@ -68,7 +70,10 @@
import org.teiid.query.sql.lang.UnaryFromClause;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.navigator.DeepPostOrderNavigator;
+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;
@@ -234,9 +239,45 @@
if (!CapabilitiesUtil.useAnsiJoin(RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata), metadata, capFinder)) {
simplifyFromClause(query);
}
+ if (columns.isEmpty()) {
+ if (CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata), metadata, capFinder)) {
+ select.addSymbol(new ExpressionSymbol("dummy", new Constant(1))); //$NON-NLS-1$
+ } else {
+ //TODO: need to ensure the type is consistent
+ //- should be rare as the source would typically support select expression if it supports union
+ select.addSymbol(selectOutputElement(query.getFrom().getGroups(), metadata));
+ }
+ }
return query;
}
+
+ /**
+ * Find a selectable element in the specified groups. This is a helper for fixing
+ * the "no elements" case.
+ *
+ * @param groups Bunch of groups
+ * @param metadata Metadata implementation
+ * @throws QueryPlannerException
+ */
+ private ElementSymbol selectOutputElement(Collection<GroupSymbol> groups, QueryMetadataInterface metadata)
+ throws QueryMetadataException, TeiidComponentException {
+ // Find a group with selectable elements and pick the first one
+ for (GroupSymbol group : groups) {
+ List<ElementSymbol> elements = (List<ElementSymbol>)ResolverUtil.resolveElementsInGroup(group, metadata);
+
+ for (ElementSymbol element : elements) {
+ if(metadata.elementSupports(element.getMetadataID(), SupportConstants.Element.SELECT)) {
+ element = (ElementSymbol)element.clone();
+ element.setGroupSymbol(group);
+ return element;
+ }
+ }
+ }
+
+ return null;
+ }
+
void buildQuery(PlanNode accessRoot, PlanNode node, Query query, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
//visit source and join nodes as they appear
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-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -341,7 +341,6 @@
}
}
- //TODO: in each of the cases below, check to see if the offending projected symbol is actually used in the upper frame
List<ElementSymbol> virtualElements = symbolMap.getKeys();
for (int i = 0; i < selectSymbols.size(); i++) {
SingleElementSymbol symbol = selectSymbols.get(i);
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -407,7 +407,9 @@
List<SingleElementSymbol> projectedViewSymbols = Util.deepClone(symbolMap.getKeys(), SingleElementSymbol.class);
- SymbolMap viewMapping = SymbolMap.createSymbolMap(NodeEditor.findParent(unionSource, NodeConstants.Types.SOURCE).getGroups().iterator().next(), projectedViewSymbols, metadata);
+ PlanNode parent = NodeEditor.findParent(unionSource, NodeConstants.Types.SOURCE);
+ SymbolMap parentMap = (SymbolMap) parent.getProperty(NodeConstants.Info.SYMBOL_MAP);
+ SymbolMap viewMapping = SymbolMap.createSymbolMap(parentMap.getKeys(), projectedViewSymbols);
for (AggregateSymbol agg : aggregates) {
agg = (AggregateSymbol)agg.clone();
ExpressionMappingVisitor.mapExpressions(agg, viewMapping.asMap());
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -23,16 +23,15 @@
package org.teiid.query.optimizer.relational.rules;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryPlannerException;
-import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
-import org.teiid.core.util.Assertion;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -42,16 +41,14 @@
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
import org.teiid.query.resolver.util.ResolverUtil;
-import org.teiid.query.sql.lang.Criteria;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.JoinType;
-import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.symbol.AggregateSymbol;
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.GroupSymbol;
import org.teiid.query.sql.util.SymbolMap;
-import org.teiid.query.sql.visitor.ElementCollectorVisitor;
+import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
import org.teiid.query.util.CommandContext;
@@ -71,155 +68,42 @@
QueryMetadataException,
TeiidComponentException {
- try {
- removeOptionalJoinNodes(plan, metadata, capFinder, null);
- } catch (QueryResolverException e) {
- throw new TeiidComponentException(e);
- }
+ List<PlanNode> joinNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.JOIN);
+ HashSet<PlanNode> removedNodes = new HashSet<PlanNode>();
+ for (PlanNode planNode : joinNodes) {
+ if (removedNodes.contains(planNode)) {
+ continue;
+ }
+ Set<GroupSymbol> groups = GroupsUsedByElementsVisitor.getGroups((Collection<? extends LanguageObject>)planNode.getProperty(NodeConstants.Info.OUTPUT_COLS));
+ List<PlanNode> removed = removeJoin(groups, planNode, planNode.getFirstChild(), metadata);
+ if (removed != null) {
+ removedNodes.addAll(removed);
+ continue;
+ }
+ removed = removeJoin(groups, planNode, planNode.getLastChild(), metadata);
+ if (removed != null) {
+ removedNodes.addAll(removed);
+ }
+ }
return plan;
}
/**
- * remove optional from top to bottom
- * @throws QueryResolverException
- */
- private boolean removeOptionalJoinNodes(PlanNode node,
- QueryMetadataInterface metadata,
- CapabilitiesFinder capFinder, Set<ElementSymbol> elements) throws QueryPlannerException,
- QueryMetadataException,
- TeiidComponentException, QueryResolverException {
- if (node.getChildCount() == 0) {
- return false;
- }
-
- boolean isRoot = false;
-
- switch (node.getType()) {
-
- case NodeConstants.Types.JOIN:
- {
- if (removedJoin(node, node.getFirstChild(), elements, metadata)) {
- return true;
- }
- if (removedJoin(node, node.getLastChild(), elements, metadata)) {
- return true;
- }
- List crits = (List)node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
- ElementCollectorVisitor.getElements(crits, elements);
- elements.addAll(node.getCorrelatedReferenceElements());
- break;
- }
- case NodeConstants.Types.PROJECT:
- {
- //skip to the child project
- if (node.getProperty(NodeConstants.Info.INTO_GROUP) != null) {
- elements = null;
- node = NodeEditor.findNodePreOrder(node.getFirstChild(), NodeConstants.Types.PROJECT);
- }
-
- if (elements == null) {
- isRoot = true;
- elements = new HashSet<ElementSymbol>();
- }
-
- //if it is a grouping scenario just make it a root
- if (!isRoot && NodeEditor.findNodePreOrder(node.getFirstChild(), NodeConstants.Types.GROUP, NodeConstants.Types.PROJECT) != null) {
- isRoot = true;
- }
-
- if (isRoot) {
- List columns = (List)node.getProperty(NodeConstants.Info.PROJECT_COLS);
- ElementCollectorVisitor.getElements(columns, elements);
- elements.addAll(node.getCorrelatedReferenceElements());
- }
-
- break;
- }
- case NodeConstants.Types.SOURCE:
- {
- if (elements == null) {
- break;
- }
- SymbolMap symbolMap = (SymbolMap)node.getProperty(NodeConstants.Info.SYMBOL_MAP);
- Set convertedElements = new HashSet();
- for (ElementSymbol element : elements) {
- Expression convertedExpression = symbolMap.getMappedExpression(element);
- if (convertedExpression != null) {
- ElementCollectorVisitor.getElements(convertedExpression, convertedElements);
- }
- }
- elements = convertedElements;
- isRoot = true;
- break;
- }
- case NodeConstants.Types.SELECT: //covers having as well
- {
- if (elements != null) {
- Criteria crit = (Criteria)node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
- ElementCollectorVisitor.getElements(crit, elements);
- elements.addAll(node.getCorrelatedReferenceElements());
- }
- break;
- }
- case NodeConstants.Types.SORT:
- {
- if (elements != null) {
- OrderBy sortOrder = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
- ElementCollectorVisitor.getElements(sortOrder, elements);
- }
- break;
- }
- case NodeConstants.Types.SET_OP:
- case NodeConstants.Types.DUP_REMOVE:
- {
- //allow project nodes to be seen as roots
- elements = null;
- break;
- }
- }
-
- //if this is a root then keep removing optional nodes until none can be removed
- if (isRoot) {
- boolean optionalRemoved = false;
- do {
- optionalRemoved = removeOptionalJoinNodes(node.getFirstChild(), metadata, capFinder, elements);
- } while (optionalRemoved);
- return false;
- }
-
- //otherwise recurse through the children
- Iterator iter = node.getChildren().iterator();
-
- while (node.getChildCount() >= 1 && iter.hasNext()) {
- if (removeOptionalJoinNodes((PlanNode)iter.next(), metadata, capFinder, elements)) {
- return true;
- }
- }
- return false;
- }
-
- /**
* remove the optional node if possible
* @throws QueryPlannerException
+ * @throws TeiidComponentException
+ * @throws QueryMetadataException
*/
- private boolean removedJoin(PlanNode joinNode, PlanNode optionalNode,
- Set elements, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
- Set groups = optionalNode.getGroups();
-
- Assertion.isNotNull(elements);
-
- for (Iterator i = elements.iterator(); i.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)i.next();
- if (groups.contains(symbol.getGroupSymbol())) {
- return false; //groups contain an output symbol, don't remove
- }
+ private List<PlanNode> removeJoin(Set<GroupSymbol> groups, PlanNode joinNode, PlanNode optionalNode, QueryMetadataInterface metadata) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+ if (!Collections.disjoint(optionalNode.getGroups(), groups)) {
+ return null;
}
-
+
JoinType jt = (JoinType)joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
if (!optionalNode.hasBooleanProperty(NodeConstants.Info.IS_OPTIONAL) &&
(jt != JoinType.JOIN_LEFT_OUTER || optionalNode != joinNode.getLastChild() || useNonDistinctRows(joinNode.getParent()))) {
- return false;
+ return null;
}
// remove the parent node and move the sibling node upward
PlanNode parentNode = joinNode.getParent();
@@ -227,16 +111,16 @@
NodeEditor.removeChildNode(parentNode, joinNode);
// correct the parent nodes that may be using optional elements
- for (GroupSymbol optionalGroup : optionalNode.getGroups()) {
+ /*for (GroupSymbol optionalGroup : optionalNode.getGroups()) {
List<ElementSymbol> optionalElements = ResolverUtil.resolveElementsInGroup(optionalGroup, metadata);
List<Constant> replacements = new ArrayList<Constant>(optionalElements.size());
for (ElementSymbol elementSymbol : optionalElements) {
replacements.add(new Constant(null, elementSymbol.getType()));
}
FrameUtil.convertFrame(parentNode, optionalGroup, null, SymbolMap.createSymbolMap(optionalElements, replacements).asMap(), metadata);
- }
+ }*/
- return true;
+ return NodeEditor.findAllNodes(optionalNode, NodeConstants.Types.JOIN);
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -48,7 +48,7 @@
*/
public class FunctionCollectorVisitor extends LanguageVisitor {
- private Collection functions;
+ private Collection<Function> functions;
private String functionName;
@@ -58,7 +58,7 @@
* @param elements Collection to use for elements
* @throws IllegalArgumentException If elements is null
*/
- public FunctionCollectorVisitor(Collection functions) {
+ public FunctionCollectorVisitor(Collection<Function> functions) {
this(functions, null);
}
@@ -68,7 +68,7 @@
* @param elements Collection to use for elements
* @throws IllegalArgumentException If elements is null
*/
- public FunctionCollectorVisitor(Collection functions, String functionName) {
+ public FunctionCollectorVisitor(Collection<Function> functions, String functionName) {
if(functions == null) {
throw new IllegalArgumentException(QueryPlugin.Util.getString("ERR.015.010.0022")); //$NON-NLS-1$
}
@@ -81,7 +81,7 @@
* after the visitor has been run on the language object tree.
* @return Collection of {@link org.teiid.query.sql.symbol.ElementSymbol}
*/
- public Collection getFunctions() {
+ public Collection<Function> getFunctions() {
return this.functions;
}
@@ -101,7 +101,7 @@
* @param obj Language object
* @param elements Collection to collect elements in
*/
- public static final void getFunctions(LanguageObject obj, Collection functions) {
+ public static final void getFunctions(LanguageObject obj, Collection<Function> functions) {
getFunctions(obj, functions, false);
}
@@ -110,7 +110,7 @@
* @param obj Language object
* @param elements Collection to collect elements in
*/
- public static final void getFunctions(LanguageObject obj, Collection functions, boolean deep) {
+ public static final void getFunctions(LanguageObject obj, Collection<Function> functions, boolean deep) {
FunctionCollectorVisitor visitor = new FunctionCollectorVisitor(functions);
if (!deep) {
PreOrderNavigator.doVisit(obj, visitor);
@@ -127,16 +127,16 @@
* @param removeDuplicates True to remove duplicates
* @return Collection of {@link org.teiid.query.sql.symbol.ElementSymbol}
*/
- public static final Collection getFunctions(LanguageObject obj, boolean removeDuplicates) {
+ public static final Collection<Function> getFunctions(LanguageObject obj, boolean removeDuplicates) {
return getFunctions(obj, removeDuplicates, false);
}
- public static final Collection getFunctions(LanguageObject obj, boolean removeDuplicates, boolean deep) {
- Collection functions = null;
+ public static final Collection<Function> getFunctions(LanguageObject obj, boolean removeDuplicates, boolean deep) {
+ Collection<Function> functions = null;
if(removeDuplicates) {
- functions = new HashSet();
+ functions = new HashSet<Function>();
} else {
- functions = new ArrayList();
+ functions = new ArrayList<Function>();
}
getFunctions(obj, functions, deep);
return functions;
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestAccessPatterns.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestAccessPatterns.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestAccessPatterns.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -213,7 +213,7 @@
@Test public void testPushingCriteriaThroughFrameAccessPattern0() {
TestOptimizer.helpPlan("select * from vm1.g9 where vm1.g9.e1='abc'", FakeMetadataFactory.example1Cached(), //$NON-NLS-1$
- new String[] { "SELECT pm4.g1.e1 FROM pm4.g1 WHERE pm4.g1.e1 = 'abc'", //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm4.g1 WHERE pm4.g1.e1 = 'abc'", //$NON-NLS-1$
"SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1 WHERE pm1.g1.e1 = 'abc'" } ); //$NON-NLS-1$
}
@@ -232,7 +232,7 @@
@Test public void testPushingCriteriaThroughFrameAccessPattern3() {
TestOptimizer.helpPlan("select * from vm1.g1, vm1.g9 where vm1.g1.e1='abc' and vm1.g1.e1=vm1.g9.e1", FakeMetadataFactory.example1Cached(), //$NON-NLS-1$
- new String[] {"SELECT pm4.g1.e1 FROM pm4.g1 WHERE pm4.g1.e1 = 'abc'", //$NON-NLS-1$
+ new String[] {"SELECT 1 FROM pm4.g1 WHERE pm4.g1.e1 = 'abc'", //$NON-NLS-1$
"SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1 WHERE pm1.g1.e1 = 'abc'", //$NON-NLS-1$
"SELECT g1__1.e1, g1__1.e2, g1__1.e3, g1__1.e4 FROM pm1.g1 AS g1__1 WHERE g1__1.e1 = 'abc'"} ); //$NON-NLS-1$
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -22,6 +22,7 @@
package org.teiid.query.optimizer;
+import org.junit.Test;
import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
@@ -29,18 +30,16 @@
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.unittest.FakeMetadataFactory;
-import junit.framework.TestCase;
-
/**
* expressions in group use lacks robust support in MySQL, PostGres, and Derby Expressions and it's nothing more than syntactic sugar for an inline view,
* a new approach was taken to use inline views rather than a non ANSI group by construct.
*
* Later we can add a connector binding property to support non-select expressions in group by.
*/
-public class TestExpressionsInGroupBy extends TestCase {
+public class TestExpressionsInGroupBy {
- public void testCase1565() throws Exception {
+ @Test public void testCase1565() throws Exception {
// Create query
String sql = "SELECT x, COUNT(*) FROM (SELECT convert(TimestampValue, date) AS x FROM bqt1.smalla) as y GROUP BY x"; //$NON-NLS-1$
@@ -64,7 +63,7 @@
}
// Merge across multiple virtual groups - should be same outcome as testCase1565
- public void testCase1565_2() throws Exception {
+ @Test public void testCase1565_2() throws Exception {
// Create query
String sql = "SELECT x, COUNT(*) FROM (SELECT convert(TimestampValue, date) AS x FROM (SELECT TimestampValue from bqt1.smalla) as z) as y GROUP BY x"; //$NON-NLS-1$
@@ -88,7 +87,7 @@
}
// Merge across multiple virtual groups above the physical
- public void testCase1565_3() throws Exception {
+ @Test public void testCase1565_3() throws Exception {
String sql = "SELECT x, COUNT(*) FROM (SELECT convert(TimestampValue, date) AS x FROM (SELECT TimestampValue from bqt1.smalla) as z) as y GROUP BY x"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -115,7 +114,7 @@
}
// Test what happens when not all the functions in the virtual SELECT can be pushed
- public void testCase1565_4() throws Exception {
+ @Test public void testCase1565_4() throws Exception {
// Create query
String sql = "SELECT x, y FROM (SELECT convert(TimestampValue, date) as x, length(stringkey) as y from bqt1.smalla) as z GROUP BY x, y"; //$NON-NLS-1$
@@ -153,7 +152,7 @@
}
// Test nested functions
- public void testCase1565_5() throws Exception {
+ @Test public void testCase1565_5() throws Exception {
// Create query
String sql = "SELECT x, COUNT(*) FROM (SELECT convert(intkey + 5, string) AS x FROM bqt1.smalla) as y GROUP BY x"; //$NON-NLS-1$
@@ -191,7 +190,7 @@
}
// SELECT SUM(x) FROM (SELECT IntKey+1 AS x FROM BQT1.SmallA) AS g
- public void testAggregateNoGroupByWithNestedFunction() {
+ @Test public void testAggregateNoGroupByWithNestedFunction() {
ProcessorPlan plan = TestOptimizer.helpPlan("SELECT SUM(x) FROM (SELECT IntKey+1 AS x FROM BQT1.SmallA) AS g", FakeMetadataFactory.exampleBQTCached(), //$NON-NLS-1$
new String[] { "SELECT IntKey FROM BQT1.SmallA" }); //$NON-NLS-1$
@@ -216,7 +215,7 @@
/**
* Without inline view support the agg is not pushed down
*/
- public void testFunctionInGroupBy() {
+ @Test public void testFunctionInGroupBy() {
String sql = "SELECT sum (IntKey), case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
"FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000 +' else '0-999' end"; //$NON-NLS-1$
@@ -261,7 +260,7 @@
*
* @since 4.2
*/
- public void testFunctionInGroupByCantPush() {
+ @Test public void testFunctionInGroupByCantPush() {
String sql = "SELECT sum (IntKey), case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
"FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000 +' else '0-999' end"; //$NON-NLS-1$
@@ -305,7 +304,7 @@
*
* @since 4.2
*/
- public void testFunctionInGroupByHavingCantPush() {
+ @Test public void testFunctionInGroupByHavingCantPush() {
String sql = "SELECT sum (IntKey), case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
"FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
"HAVING case when IntKey>=5000 then '5000 +' else '0-999' end = '5000 +'"; //$NON-NLS-1$
@@ -349,7 +348,7 @@
*
* @since 4.2
*/
- public void testFunctionInGroupByCantPushRewritten() {
+ @Test public void testFunctionInGroupByCantPushRewritten() {
String sql = "SELECT SUM(IntKey), c FROM (SELECT IntKey, case when IntKey>=5000 then '5000 +' else '0-999' end AS c FROM BQT1.SmallA) AS temp GROUP BY c"; //$NON-NLS-1$
// Plan query
@@ -386,7 +385,7 @@
});
}
- public void testFunctionOfAggregateCantPush2() {
+ @Test public void testFunctionOfAggregateCantPush2() {
String sql = "SELECT SUM(length(StringKey || 'x')) + 1 AS x FROM BQT1.SmallA GROUP BY StringKey || 'x' HAVING space(MAX(length((StringKey || 'x') || 'y'))) = ' '"; //$NON-NLS-1$
// Plan query
@@ -419,7 +418,7 @@
}
- public void testDontPushGroupByUnsupportedFunction() throws Exception {
+ @Test public void testDontPushGroupByUnsupportedFunction() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_GROUP_BY, true);
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -154,7 +154,7 @@
metadata,
null,
capFinder,
- new String[] {"SELECT bqt1.smalla.intkey FROM bqt1.smalla", "SELECT BQT2.SmallA.IntKey FROM bqt2.smalla"}, true ); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] {"SELECT bqt1.smalla.intkey FROM bqt1.smalla", "SELECT 1 FROM bqt2.smalla"}, true ); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -266,7 +266,7 @@
String sql = "select bqt1.smalla.intkey from bqt1.smalla inner join (select bqt3.smalla.intkey from bqt2.smalla left outer join bqt3.smalla on bqt2.smalla.intkey = bqt3.smalla.intkey and bqt3.smalla.intkey = 1) foo on bqt1.smalla.intkey = foo.intkey"; //$NON-NLS-1$
// Plan query
- ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.IntKey FROM bqt2.smalla AS g_0", "SELECT g_0.intkey AS c_0 FROM bqt1.smalla AS g_0 ORDER BY c_0"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT 1 FROM bqt2.smalla AS g_0", "SELECT g_0.intkey AS c_0 FROM bqt1.smalla AS g_0 ORDER BY c_0"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
TestOptimizer.checkNodeTypes(plan, new int[] {
3, // Access
@@ -293,7 +293,7 @@
String sql = "select bqt1.smalla.intkey from bqt1.smalla left outer join (select bqt3.smalla.intkey from bqt3.smalla where bqt3.smalla.intkey = 1) foo on bqt1.smalla.intkey = foo.intkey"; //$NON-NLS-1$
// Plan query
- ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.IntKey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.intkey FROM bqt1.smalla AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT 1 FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.intkey FROM bqt1.smalla AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinWithFunction.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinWithFunction.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinWithFunction.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -130,8 +130,8 @@
String leftQuery = "SELECT pm1.g1.e1 as ID, pm1.g1.e2, pm1.g1.e3, pm1.g1.e4, RAND() AS RandomLeft " //$NON-NLS-1$
+ "FROM pm1.g1"; //$NON-NLS-1$
// source query for other side of a JOIN
- String rightQuery = "SELECT pm2.g2.e1 as ID, pm2.g2.e2, pm2.g2.e3, pm2.g2.e4 " //$NON-NLS-1$
- + "FROM pm2.g2"; //$NON-NLS-1$
+ String rightQuery = "SELECT pm1.g2.e1 as ID, pm1.g2.e2, pm1.g2.e3, pm1.g2.e4 " //$NON-NLS-1$
+ + "FROM pm1.g2"; //$NON-NLS-1$
// User Command
/*
@@ -147,7 +147,7 @@
// The user command should result in two atomic commands
String[] expected = new String[] {
"SELECT g_0.e1, g_0.e2, g_0.e3, g_0.e4 FROM pm1.g1 AS g_0", //$NON-NLS-1$
- "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2, g_0.e4 AS c_3 FROM pm2.g2 AS g_0 ORDER BY c_0", //$NON-NLS-1$
+ "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2, g_0.e4 AS c_3 FROM pm1.g2 AS g_0 ORDER BY c_0", //$NON-NLS-1$
};
// create a plan and assert our atomic queries
@@ -169,7 +169,40 @@
0 // UnionAll
});
}
+
+ /**
+ * Note that we detect the lower rand is not used
+ */
+ public void testNonDeterministicPreJoin1() throws Exception {
+ // source query for one side of a JOIN
+ String leftQuery = "SELECT pm1.g1.e1 as ID, pm1.g1.e2, pm1.g1.e3, pm1.g1.e4, RAND() AS RandomLeft " //$NON-NLS-1$
+ + "FROM pm1.g1"; //$NON-NLS-1$
+ // source query for other side of a JOIN
+ String rightQuery = "SELECT pm1.g2.e1 as ID, pm1.g2.e2, pm1.g2.e3, pm1.g2.e4 " //$NON-NLS-1$
+ + "FROM pm1.g2"; //$NON-NLS-1$
+ // User Command
+ /*
+ * Return everything from the JOIN. TopRandom is the use of RAND() on
+ * the user command while RandomLeft is the use of RAND() within a
+ * source node.
+ */
+ String sql = "SELECT l.ID, l.e2, l.e3, l.e4, r.ID, r.e2, r.e3, r.e4 " + //$NON-NLS-1$
+ "FROM (" + leftQuery + ") AS l, " + //$NON-NLS-1$ //$NON-NLS-2$
+ "(" + rightQuery + ") AS r " + //$NON-NLS-1$ //$NON-NLS-2$
+ "WHERE l.ID = r.ID"; //$NON-NLS-1$
+
+ // The user command should result in two atomic commands
+ String[] expected = new String[] {
+ "SELECT g_0.e1, g_0.e2, g_0.e3, g_0.e4, g_1.e1, g_1.e2, g_1.e3, g_1.e4 FROM pm1.g1 AS g_0, pm1.g2 AS g_1 WHERE g_0.e1 = g_1.e1", //$NON-NLS-1$
+ };
+
+ // create a plan and assert our atomic queries
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql, TestOptimizer.example1(), expected,
+ ComparisonMode.EXACT_COMMAND_STRING);
+ TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
+ }
+
/**
* <p>Test the use of a non-deterministic function on the sub-command of a user
* command and the user command itself, which performs a JOIN of two sources.</p>
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -949,8 +949,8 @@
/** defect #4997 */
@Test public void testCountStarNoRows() {
ProcessorPlan plan = helpPlan("select count(*) from vm1.u4", example1(), //$NON-NLS-1$
- new String[] { "SELECT e1 FROM pm1.g2", //$NON-NLS-1$
- "SELECT e1 FROM pm1.g1" } ); //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm1.g2", //$NON-NLS-1$
+ "SELECT 1 FROM pm1.g1" } ); //$NON-NLS-1$
checkNodeTypes(plan, new int[] {
2, // Access
0, // DependentAccess
@@ -962,7 +962,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
1 // UnionAll
@@ -971,7 +971,7 @@
@Test public void testPushingCriteriaWithCopy() {
ProcessorPlan plan = helpPlan("select vm1.u1.e1 from vm1.u1, pm1.g1 where vm1.u1.e1='abc' and vm1.u1.e1=pm1.g1.e1", example1(), //$NON-NLS-1$
- new String[] { "SELECT pm1.g1.e1 FROM pm1.g1 WHERE pm1.g1.e1 = 'abc'", //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm1.g1 WHERE pm1.g1.e1 = 'abc'", //$NON-NLS-1$
"SELECT pm1.g3.e1, pm1.g3.e2, pm1.g3.e3, pm1.g3.e4 FROM pm1.g3 WHERE pm1.g3.e1 = 'abc'", //$NON-NLS-1$
"SELECT pm1.g2.e1, pm1.g2.e2, pm1.g2.e3, pm1.g2.e4 FROM pm1.g2 WHERE pm1.g2.e1 = 'abc'", //$NON-NLS-1$
"SELECT pm1.g1.e1, pm1.g1.e2, pm1.g1.e3, pm1.g1.e4 FROM pm1.g1 WHERE pm1.g1.e1 = 'abc'" } ); //$NON-NLS-1$
@@ -1057,17 +1057,17 @@
@Test public void testDefect5282_1() {
helpPlan("select * FROM vm1.a4 WHERE vm1.a4.count > 0", example1(), //$NON-NLS-1$
- new String[] { "SELECT pm1.g1.e1 FROM pm1.g1" } ); //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm1.g1" } ); //$NON-NLS-1$
}
@Test public void testDefect5282_2() {
helpPlan("select count(*) FROM vm1.a4", example1(), //$NON-NLS-1$
- new String[] { "SELECT pm1.g1.e1 FROM pm1.g1" } ); //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm1.g1" } ); //$NON-NLS-1$
}
@Test public void testDefect5282_3() {
helpPlan("select * FROM vm1.a5 WHERE vm1.a5.count > 0", example1(), //$NON-NLS-1$
- new String[] { "SELECT pm1.g1.e1 FROM pm1.g1" } ); //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm1.g1" } ); //$NON-NLS-1$
}
@Test public void testDepJoinHintBaseline() throws Exception {
@@ -1100,8 +1100,8 @@
@Test public void testDefect6425_2() {
helpPlan("select count(*) from vm1.u9", example1(), //$NON-NLS-1$
- new String[] { "SELECT e1 FROM pm1.g1", //$NON-NLS-1$
- "SELECT e1 FROM pm1.g2" } ); //$NON-NLS-1$
+ new String[] { "SELECT 1 FROM pm1.g1", //$NON-NLS-1$
+ "SELECT 1 FROM pm1.g2" } ); //$NON-NLS-1$
}
@Test public void testPushMatchCritWithReference() {
@@ -2714,7 +2714,7 @@
*/
@Test public void testCrossJoinNoElementCriteriaOptimization2() {
ProcessorPlan plan = helpPlan("select Y.e1, Y.e2 FROM vm1.g1 X, vm1.g1 Y where {b'true'} = {b'true'}", example1(), //$NON-NLS-1$
- new String[]{"SELECT g1__1.e1 FROM pm1.g1 AS g1__1", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"}); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[]{"SELECT 1 FROM pm1.g1 AS g1__1", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"}); //$NON-NLS-1$ //$NON-NLS-2$
checkNodeTypes(plan, new int[] {
2, // Access
0, // DependentAccess
@@ -2738,7 +2738,7 @@
*/
@Test public void testCrossJoinNoElementCriteriaOptimization3() {
ProcessorPlan plan = helpPlan("select Y.e1, Y.e2 FROM vm1.g1 X, vm1.g1 Y where {b'true'} in (select e3 FROM vm1.g1)", example1(), //$NON-NLS-1$
- new String[]{"SELECT g1__1.e1 FROM pm1.g1 AS g1__1", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"}); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[]{"SELECT 1 FROM pm1.g1 AS g1__1", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"}); //$NON-NLS-1$ //$NON-NLS-2$
checkNodeTypes(plan, new int[] {
2, // Access
0, // DependentAccess
@@ -2768,7 +2768,7 @@
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
ProcessorPlan plan = helpPlan("select Y.e1, Y.e2 FROM vm1.g1 X, vm1.g1 Y where {b'true'} in (select e3 FROM vm1.g1)", example1(), null, capFinder, //$NON-NLS-1$
- new String[]{"SELECT g1__1.e1 FROM pm1.g1 AS g1__1 WHERE TRUE IN (SELECT pm1.g1.e3 FROM pm1.g1)", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"}, true); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[]{"SELECT 1 FROM pm1.g1 AS g1__1 WHERE TRUE IN (SELECT pm1.g1.e3 FROM pm1.g1)", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"}, true); //$NON-NLS-1$ //$NON-NLS-2$
checkNodeTypes(plan, new int[] {
2, // Access
0, // DependentAccess
@@ -4488,7 +4488,7 @@
ProcessorPlan plan = helpPlan(sql,
FakeMetadataFactory.exampleBQTCached(),
null, capFinder,
- new String[] {"SELECT '' AS y FROM BQT1.SmallA AS a UNION ALL SELECT '' FROM bqt1.smallb AS b"}, //$NON-NLS-1$
+ new String[] {"SELECT 1 AS c_0 FROM BQT1.SmallA AS a UNION ALL SELECT 1 AS c_0 FROM bqt1.smallb AS b"}, //$NON-NLS-1$
SHOULD_SUCCEED );
checkNodeTypes(plan, new int[] {
@@ -6409,7 +6409,7 @@
capFinder.addCapabilities("pm2", caps); //$NON-NLS-1$
helpPlan("select pm2.g1.e1 FROM pm2.g1 CROSS JOIN pm2.g2", example1(), null, capFinder, //$NON-NLS-1$
- new String[] { "SELECT pm2.g1.e1 FROM pm2.g1", "SELECT pm2.g2.e1 FROM pm2.g2"}, true ); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] { "SELECT pm2.g1.e1 FROM pm2.g1", "SELECT 1 FROM pm2.g2"}, true ); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -6430,7 +6430,7 @@
String sql = "select count(*) from (select intkey from bqt1.smalla union all select intkey from bqt1.smallb) as a"; //$NON-NLS-1$
ProcessorPlan plan = helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), null, capFinder,
- new String[] {"SELECT COUNT(*) FROM (SELECT intkey FROM bqt1.smalla UNION ALL SELECT intkey FROM bqt1.smallb) AS a"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$
+ new String[] {"SELECT COUNT(*) FROM (SELECT 1 FROM bqt1.smalla UNION ALL SELECT 1 FROM bqt1.smallb) AS a"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$
checkNodeTypes(plan, FULL_PUSHDOWN);
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestRuleRaiseNull.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestRuleRaiseNull.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestRuleRaiseNull.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -22,8 +22,11 @@
package org.teiid.query.optimizer;
+import static org.junit.Assert.*;
+
import java.util.Arrays;
+import org.junit.Test;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
@@ -33,11 +36,7 @@
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.unittest.FakeMetadataFactory;
-import junit.framework.TestCase;
-
-
-
-public class TestRuleRaiseNull extends TestCase {
+public class TestRuleRaiseNull {
public static final int[] FULLY_NULL = new int[] {
0, // Access
@@ -64,7 +63,7 @@
* never equals anything). Expected behavior is that a NullNode is inserted in place of the
* unnecessary access node.
*/
- public void testUnionCriteriaOptimization() {
+ @Test public void testUnionCriteriaOptimization() {
String sql = "select * from ( select intkey as cola, null as colb, intnum as colc from bqt1.smalla union all select null, intkey, intnum from bqt2.smalla) as X where X.cola = 1"; //$NON-NLS-1$
@@ -75,7 +74,7 @@
}
- public void testRaiseNullWithInnerJoin() {
+ @Test public void testRaiseNullWithInnerJoin() {
String sql = "select b.intkey from (select intkey from bqt1.smalla where 1 = 0) a inner join (select intkey from bqt1.smallb) b on (a.intkey = b.intkey)"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -83,7 +82,7 @@
TestOptimizer.checkNodeTypes(plan, FULLY_NULL);
}
- public void testRaiseNullWithFullOuterJoin() {
+ @Test public void testRaiseNullWithFullOuterJoin() {
String sql = "select b.intkey from (select intkey from bqt1.smalla) a full outer join (select intkey from bqt1.smallb where 1 = 0) b on (a.intkey = b.intkey)"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -91,7 +90,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithOuterJoin() {
+ @Test public void testRaiseNullWithOuterJoin() {
String sql = "select b.intkey from (select intkey from bqt1.smalla) a left outer join (select intkey from bqt1.smallb where 1 = 0) b on (a.intkey = b.intkey)"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -99,7 +98,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithOuterJoin1() {
+ @Test public void testRaiseNullWithOuterJoin1() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
@@ -112,7 +111,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithUnion() {
+ @Test public void testRaiseNullWithUnion() {
String sql = "select b.x from (select intkey as x from bqt1.smalla where 1 = 0 union all select intnum as y from bqt1.smalla) b"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -122,7 +121,7 @@
assertEquals(Arrays.asList(new Object[] {new ElementSymbol("b.x")}), plan.getOutputElements()); //$NON-NLS-1$
}
- public void testRaiseNullWithUnion1() {
+ @Test public void testRaiseNullWithUnion1() {
String sql = "select b.intkey from (select intkey from bqt1.smalla union all select intnum from bqt1.smalla where 1 = 0) b"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -130,7 +129,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithUnion2() {
+ @Test public void testRaiseNullWithUnion2() {
String sql = "select b.intkey, b.x from (select intkey, intnum as x from bqt1.smalla where 1 = 0 union all select intnum as a, null from bqt1.smalla union all select 1 as z, intkey as b from bqt1.smallb) b"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -153,7 +152,7 @@
});
}
- public void testRaiseNullWithUnion3() {
+ @Test public void testRaiseNullWithUnion3() {
String sql = "select intkey, intnum as x from bqt1.smalla where 1 = 0 union all select intnum, intkey as z from bqt1.smalla where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -161,7 +160,7 @@
TestOptimizer.checkNodeTypes(plan, FULLY_NULL);
}
- public void testRaiseNullWithUnion4() throws Exception {
+ @Test public void testRaiseNullWithUnion4() throws Exception {
String sql = "select b.intkey, b.x from (select intkey, intnum as x from bqt1.smalla where 1 = 0 union all select 1 as z, intkey as b from bqt1.smallb) b inner join bqt1.smalla on b.intkey = bqt1.smalla.intkey"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -169,7 +168,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithUnion5() {
+ @Test public void testRaiseNullWithUnion5() {
String sql = "select intkey from bqt1.smalla union all select intkey from bqt2.smalla where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -177,7 +176,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithUnion6() {
+ @Test public void testRaiseNullWithUnion6() {
String sql = "select intkey from bqt1.smalla union all select intkey from bqt2.smalla union all select intkey from bqt2.smalla where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -200,17 +199,17 @@
});
}
- public void testPushCriteriaThroughUnion9() {
+ @Test public void testPushCriteriaThroughUnion9() {
TestOptimizer.helpPlan("select * from vm1.u8 where const = 's1'", TestOptimizer.example1(), //$NON-NLS-1$
new String[] { "SELECT 's1', e1 FROM pm1.g1" } ); //$NON-NLS-1$
}
- public void testPushCriteriaThroughUnion10() {
+ @Test public void testPushCriteriaThroughUnion10() {
TestOptimizer.helpPlan("select * from vm1.u8 where const = 's3'", TestOptimizer.example1(), //$NON-NLS-1$
new String[] { "SELECT 's3', e1 FROM pm1.g3" } ); //$NON-NLS-1$
}
- public void testRaiseNullWithOuterJoinAndHaving() {
+ @Test public void testRaiseNullWithOuterJoinAndHaving() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
@@ -242,7 +241,7 @@
* Ensures proper handling of the removal of the first branch and
* duplicate symbol names in the next branch
*/
- public void testRaiseNullWithUnion7() throws Exception {
+ @Test public void testRaiseNullWithUnion7() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_UNION, true);
@@ -260,7 +259,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithUnionOrderBy() {
+ @Test public void testRaiseNullWithUnionOrderBy() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
@@ -276,7 +275,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithGroupBy() {
+ @Test public void testRaiseNullWithGroupBy() {
String sql = "select max(e2), e1 from pm1.g1 where 1 = 0 group by e1"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.example1Cached(), new String[]{});
@@ -284,7 +283,7 @@
TestOptimizer.checkNodeTypes(plan, FULLY_NULL);
}
- public void testRaiseNullWithGroupBy1() {
+ @Test public void testRaiseNullWithGroupBy1() {
String sql = "select max(e2) from pm1.g1 where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.example1Cached(), new String[]{});
@@ -307,7 +306,7 @@
});
}
- public void testRaiseNullWithExcept() {
+ @Test public void testRaiseNullWithExcept() {
String sql = "select e1 from pm1.g1 except select e2 from pm1.g2 where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.example1Cached(), new String[]{"SELECT DISTINCT g_0.e1 FROM pm1.g1 AS g_0"}); //$NON-NLS-1$
@@ -315,7 +314,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithIntersect() {
+ @Test public void testRaiseNullWithIntersect() {
String sql = "select max(e2) from pm1.g1 intersect select e2 from pm1.g2 where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.example1Cached(), new String[]{});
@@ -328,19 +327,19 @@
* but instead is cleaned up properly later
* See defect 9865
*/
- public void testCrossJoinNoElementCriteriaOptimization() {
+ @Test public void testCrossJoinNoElementCriteriaOptimization() {
ProcessorPlan plan = TestOptimizer.helpPlan("select Y.e1, Y.e2 FROM vm1.g1 X, vm1.g1 Y where {b'true'} = {b'false'}", TestOptimizer.example1(), //$NON-NLS-1$
new String[0]);
TestOptimizer.checkNodeTypes(plan, FULLY_NULL);
}
- public void testSelectLiteralFalseCriteria() {
+ @Test public void testSelectLiteralFalseCriteria() {
ProcessorPlan plan = TestOptimizer.helpPlan("Select 'x' from pm1.g1 where 1=0", TestOptimizer.example1(), //$NON-NLS-1$
new String[] { });
TestOptimizer.checkNodeTypes(plan, FULLY_NULL);
}
- public void testRaiseNullWithUnionNotAll() {
+ @Test public void testRaiseNullWithUnionNotAll() {
String sql = "select intkey from bqt2.smalla union select intkey from bqt2.smalla where 1 = 0"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(),
@@ -348,7 +347,7 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- public void testRaiseNullWithUnionAndAliases() {
+ @Test public void testRaiseNullWithUnionAndAliases() {
String sql = "select pm1.g1.e1 from pm1.g1, (select e1 from pm1.g1 where (1 = 0) union all select e1 as x from pm1.g2) x where pm1.g1.e1 <> x.e1"; //$NON-NLS-1$
RelationalPlan plan = (RelationalPlan)TestOptimizer.helpPlan(sql, FakeMetadataFactory.example1Cached(),
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-14 20:12:15 UTC (rev 2905)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-14 20:34:03 UTC (rev 2906)
@@ -6213,8 +6213,8 @@
// Construct data manager with data
HardcodedDataManager dataManager = new HardcodedDataManager();
- dataManager.addData("SELECT g_0.a FROM p1.t AS g_0", //$NON-NLS-1$
- new List[] { Arrays.asList(new Object[] { new Integer(1) })});
+ dataManager.addData("SELECT 1 AS c_0 FROM p1.t AS g_1 UNION ALL SELECT 1 AS c_0 FROM p1.t AS g_0", //$NON-NLS-1$
+ new List[] { Arrays.asList(1), Arrays.asList(1)});
helpProcess(plan, dataManager, expected);
}
14 years, 10 months
teiid SVN: r2905 - in trunk/engine/src: test/java/org/teiid/query/metadata and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-14 15:12:15 -0500 (Mon, 14 Feb 2011)
New Revision: 2905
Modified:
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java
Log:
TEIID-1467 fix for procedure visibility issue
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-14 01:30:06 UTC (rev 2904)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-14 20:12:15 UTC (rev 2905)
@@ -352,7 +352,7 @@
for (StoredProcedureInfo storedProcedureInfo : results) {
Schema schema = (Schema)storedProcedureInfo.getModelID();
- if(vdbMetaData == null || vdbMetaData.isVisible(schema.getName())){
+ if(fullyQualifiedProcedureName.equalsIgnoreCase(storedProcedureInfo.getProcedureCallableName()) || vdbMetaData == null || vdbMetaData.isVisible(schema.getName())){
if (result != null) {
throw new QueryMetadataException(QueryPlugin.Util.getString("ambiguous_procedure", fullyQualifiedProcedureName)); //$NON-NLS-1$
}
@@ -743,6 +743,10 @@
return vdbMetaData.getVersion();
}
+ public VDBMetaData getVdbMetaData() {
+ return vdbMetaData;
+ }
+
/**
* @see org.teiid.query.metadata.QueryMetadataInterface#getXMLTempGroups(java.lang.Object)
*/
Modified: trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java 2011-02-14 01:30:06 UTC (rev 2904)
+++ trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java 2011-02-14 20:12:15 UTC (rev 2905)
@@ -61,6 +61,16 @@
assertEquals("Procedure 'y' is ambiguous, use the fully qualified name instead", e.getMessage()); //$NON-NLS-1$
}
}
+
+ @Test public void testProcVisibility() throws Exception {
+ TransformationMetadata tm = exampleTransformationMetadata();
+ VDBMetaData vdb = tm.getVdbMetaData();
+ vdb.getModel("x").setVisible(false);
+ StoredProcedureInfo spi = tm.getStoredProcedureInfoForProcedure("y"); //$NON-NLS-1$
+ assertEquals("x1.y", spi.getProcedureCallableName());
+ spi = tm.getStoredProcedureInfoForProcedure("x.y"); //$NON-NLS-1$
+ assertEquals("x.y", spi.getProcedureCallableName());
+ }
private TransformationMetadata exampleTransformationMetadata()
throws TranslatorException {
14 years, 10 months
teiid SVN: r2904 - in trunk: common-core/src/main/java/org/teiid/core/util and 5 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-02-13 20:30:06 -0500 (Sun, 13 Feb 2011)
New Revision: 2904
Modified:
trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
Log:
TEIID-1163: Adding lob support for ODBC using postges 'bytea' data type. This data type does not support streaming.
Modified: trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
===================================================================
--- trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-02-14 01:30:06 UTC (rev 2904)
@@ -110,6 +110,8 @@
<property name="maxSourceRows">-1</property>
<!-- Indicates if an exception should be thrown if the specified value for Maximum Source Rows is exceeded; only up to the maximum rows will be consumed. -->
<property name="exceptionOnMaxSourceRows">true</property>
+ <!-- Maximum size of lob allowed through ODBC connection in bytes (default 5MB) -->
+ <property name="maxODBCLobSizeAllowed">5242880</property>
</bean>
<!-- JDBC Socket connection properties (SSL see below) -->
Modified: trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -90,16 +90,32 @@
* @throws IOException if a problem occurred reading the stream.
*/
public static byte[] convertToByteArray(final InputStream is, int length) throws IOException {
+ return convertToByteArray(is, length, true);
+ }
+
+ public static byte[] convertToByteArray(final InputStream is, int length, boolean close) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
- write(out, is, length);
- return out.toByteArray();
+ write(out, is, length, close);
+ out.close();
+ return out.toByteArray();
}
+
+ public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length) throws IOException {
+ return write(out, is, l_buffer, length, true);
+ }
- public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length) throws IOException {
+ public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length, boolean close) throws IOException {
int writen = 0;
try {
int l_nbytes = 0; // Number of bytes read
- while ((l_nbytes = is.read(l_buffer)) != -1) {
+ int readLength = length;
+ if (length == -1) {
+ readLength = l_buffer.length;
+ }
+ else {
+ readLength = Math.min(length, l_buffer.length);
+ }
+ while ((l_nbytes = is.read(l_buffer, 0, readLength)) != -1) {
if (length != -1 && writen > length - l_nbytes) {
out.write(l_buffer, 0, writen + l_nbytes - length);
break;
@@ -109,16 +125,22 @@
}
return writen;
} finally {
- try {
- is.close();
- } finally {
- out.close();
+ if (close) {
+ try {
+ is.close();
+ } finally {
+ out.close();
+ }
}
}
}
+
+ public static int write(final OutputStream out, final InputStream is, int length) throws IOException {
+ return write(out, is, length, true);
+ }
- public static void write(final OutputStream out, final InputStream is, int length) throws IOException {
- write(out, is, new byte[DEFAULT_READING_SIZE], length); // buffer holding bytes to be transferred
+ public static int write(final OutputStream out, final InputStream is, int length, boolean close) throws IOException {
+ return write(out, is, new byte[DEFAULT_READING_SIZE], length, close); // buffer holding bytes to be transferred
}
public static void write(final Writer out, final Reader is, int length) throws IOException {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -51,6 +51,7 @@
private int maxSourceRows = -1;
private int maxActivePlans = DEFAULT_MAX_ACTIVE_PLANS;
private CacheConfiguration resultsetCacheConfig;
+ private int maxODBCLobSizeAllowed = 5*1024*1024; // 5 MB
@ManagementProperty(description="Max active plans (default 20). Increase this value, and max threads, on highly concurrent systems - but ensure that the underlying pools can handle the increased load without timeouts.")
public int getMaxActivePlans() {
@@ -185,4 +186,13 @@
public void setMaxSourceRows(int maxSourceRows) {
this.maxSourceRows = maxSourceRows;
}
+
+ @ManagementProperty(description="Maximum Lob Size allowed over ODBC (default 5MB)")
+ public int getMaxODBCLobSizeAllowed() {
+ return this.maxODBCLobSizeAllowed;
+ }
+
+ public void setMaxODBCLobSizeAllowed(int lobSize) {
+ this.maxODBCLobSizeAllowed = lobSize;
+ }
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -192,7 +192,7 @@
if (this.odbcSocketConfiguration.getEnabled()) {
this.vdbRepository.odbcEnabled();
- this.odbcSocket = new ODBCSocketListener(this.odbcSocketConfiguration, this.dqpCore.getBufferManager(), offset);
+ this.odbcSocket = new ODBCSocketListener(this.odbcSocketConfiguration, this.dqpCore.getBufferManager(), offset, getMaxODBCLobSizeAllowed());
LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("odbc_enabled","Teiid ODBC - SSL=", (this.odbcSocketConfiguration.getSSLConfiguration().isSslEnabled()?"ON":"OFF")+" Host = "+this.odbcSocketConfiguration.getHostAddress().getHostName()+" Port = "+(this.odbcSocketConfiguration.getPortNumber()+offset))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
} else {
LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("odbc_not_enabled")); //$NON-NLS-1$
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -79,6 +79,12 @@
void flush();
+ // FunctionCallResponse (B)
+ void functionCallResponse(byte[] data);
+ void functionCallResponse(int data);
+
+ void sslDenied();
+
// unimplemented backend messages
// AuthenticationKerberosV5 (B)
@@ -95,8 +101,6 @@
// CopyInResponse (B)
// CopyOutResponse (B)
- // FunctionCallResponse (B)
-
// NoticeResponse (B)
// NotificationResponse (B)
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -56,13 +56,14 @@
void flush();
+ void functionCall(int oid);
+
+ void sslRequest();
+
// unimplemented frontend messages
// CopyData (F & B)
// CopyDone (F & B)
// CopyFail (F)
- // Flush (F)
- // FunctionCall (F)
- // SSLRequest (F)
}
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -571,7 +571,18 @@
public void flush() {
this.client.flush();
}
-
+
+ @Override
+ public void functionCall(int oid) {
+ this.client.errorOccurred(RuntimePlugin.Util.getString("lo_not_supported")); //$NON-NLS-1$
+ sync();
+ }
+
+ @Override
+ public void sslRequest() {
+ this.client.sslDenied();
+ }
+
/**
* Represents a PostgreSQL Prepared object.
*/
Modified: trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -32,10 +32,12 @@
public class ODBCSocketListener extends SocketListener {
private ODBCServerRemote.AuthenticationType authType = ODBCServerRemote.AuthenticationType.CLEARTEXT;
+ private int maxLobSize;
- public ODBCSocketListener(SocketConfiguration config, StorageManager storageManager, int portOffset) {
+ public ODBCSocketListener(SocketConfiguration config, StorageManager storageManager, int portOffset, int maxLobSize) {
//the clientserviceregistry isn't actually used by ODBC
super(config, new ClientServiceRegistryImpl(ClientServiceRegistry.Type.ODBC), storageManager, portOffset);
+ this.maxLobSize = maxLobSize;
}
@Override
@@ -49,7 +51,7 @@
pipeline.addLast("ssl", new SslHandler(engine)); //$NON-NLS-1$
}
pipeline.addLast("odbcFrontendProtocol", new PgFrontendProtocol(1 << 20)); //$NON-NLS-1$
- pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol()); //$NON-NLS-1$
+ pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol(maxLobSize)); //$NON-NLS-1$
pipeline.addLast("handler", this); //$NON-NLS-1$
return pipeline;
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -27,10 +27,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
+import java.sql.Blob;
+import java.sql.Clob;
import java.sql.ParameterMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
+import java.sql.SQLXML;
import java.sql.Types;
import java.util.Properties;
@@ -41,6 +44,8 @@
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
+import org.teiid.core.util.ObjectConverterUtil;
+import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
@@ -64,15 +69,16 @@
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_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_TEXTARRAY = 1009;
+ //private static final int PG_TYPE_TEXTARRAY = 1009;
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;
@@ -82,7 +88,12 @@
private ReflectionHelper clientProxy = new ReflectionHelper(ODBCClientRemote.class);
private ChannelHandlerContext ctx;
private MessageEvent message;
+ private int maxLobSize = (2*1024*1024); // 2 MB
+ public PgBackendProtocol(int maxLobSize) {
+ this.maxLobSize = maxLobSize;
+ }
+
@Override
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent evt) throws Exception {
if (!(evt instanceof MessageEvent)) {
@@ -210,7 +221,7 @@
if (paramType != null && paramType[i] != 0) {
type = paramType[i];
} else {
- type = PG_TYPE_VARCHAR;
+ type = convertType(meta.getParameterType(i+1));
}
writeInt(type);
}
@@ -244,8 +255,13 @@
ResultSetMetaData meta = rs.getMetaData();
sendRowDescription(meta);
}
+ int columns = rs.getMetaData().getColumnCount();
+ int[] types = new int[columns];
+ for(int i = 0; i < columns; i++) {
+ types[i] = rs.getMetaData().getColumnType(i+1);
+ }
while (rs.next()) {
- sendDataRow(rs);
+ sendDataRow(rs, columns, types);
}
sendCommandComplete(sql, 0);
} catch (SQLException e) {
@@ -331,27 +347,81 @@
sendMessage();
}
- private void sendDataRow(ResultSet rs) throws SQLException, IOException {
- int columns = rs.getMetaData().getColumnCount();
- String[] values = new String[columns];
- for (int i = 0; i < columns; i++) {
- values[i] = rs.getString(i + 1);
- }
+ private void sendDataRow(ResultSet rs, int columns, int[] types) throws SQLException, IOException {
startMessage('D');
writeShort(columns);
- for (String s : values) {
- if (s == null) {
+ for (int i = 0; i < columns; i++) {
+ byte[] bytes = getContent(rs, types[i], i+1);
+ if (bytes == null) {
writeInt(-1);
} else {
- // TODO write Binary data
- byte[] d2 = s.getBytes(this.encoding);
- writeInt(d2.length);
- write(d2);
+ writeInt(bytes.length);
+ write(bytes);
}
}
sendMessage();
}
+ private byte[] getContent(ResultSet rs, int type, int column) throws SQLException, TeiidSQLException, IOException {
+ byte[] bytes = null;
+ switch (type) {
+ case Types.BOOLEAN:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.SMALLINT:
+ case Types.INTEGER:
+ case Types.BIGINT:
+ case Types.NUMERIC:
+ case Types.DECIMAL:
+ case Types.FLOAT:
+ case Types.REAL:
+ case Types.DOUBLE:
+ case Types.TIME:
+ case Types.DATE:
+ case Types.TIMESTAMP:
+ String value = rs.getString(column);
+ if (value != null) {
+ bytes = value.getBytes(this.encoding);
+ }
+ break;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ Clob clob = rs.getClob(column);
+ if (clob != null) {
+ bytes = ObjectConverterUtil.convertToByteArray(new ReaderInputStream(clob.getCharacterStream(), this.encoding), this.maxLobSize);
+ }
+ break;
+
+ case Types.SQLXML:
+ SQLXML xml = rs.getSQLXML(column);
+ if (xml != null) {
+ bytes = ObjectConverterUtil.convertToByteArray(new ReaderInputStream(xml.getCharacterStream(), this.encoding), this.maxLobSize);
+ }
+ break;
+
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ case Types.BLOB:
+ Blob blob = rs.getBlob(column);
+ if (blob != null) {
+ bytes = toHex(ObjectConverterUtil.convertToByteArray(blob.getBinaryStream(), this.maxLobSize));
+ }
+ break;
+ default:
+ throw new TeiidSQLException("unknown datatype failed to convert");
+ }
+ return bytes;
+ }
+
+ @Override
+ public void sslDenied() {
+ ChannelBuffer buffer = ChannelBuffers.directBuffer(1);
+ buffer.writeByte('N');
+ Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());
+ }
+
private void sendErrorResponse(Throwable t) throws IOException {
trace(t.getMessage());
SQLException e = TeiidSQLException.create(t);
@@ -496,6 +566,35 @@
writeString(value);
sendMessage();
}
+
+ @Override
+ public void functionCallResponse(byte[] data) {
+ try {
+ startMessage('V');
+ if (data == null) {
+ writeInt(-1);
+ }
+ else {
+ writeInt(data.length);
+ write(data);
+ }
+ sendMessage();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void functionCallResponse(int data) {
+ try {
+ startMessage('V');
+ writeInt(4);
+ writeInt(data);
+ sendMessage();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
private void writeString(String s) throws IOException {
write(s.getBytes(this.encoding));
@@ -543,26 +642,30 @@
LogManager.logTrace(LogConstants.CTX_ODBC, msg);
}
+ /**
+ * Types.ARRAY is not supported
+ */
private static int convertType(final int type) {
switch (type) {
case Types.BOOLEAN:
- return PG_TYPE_BOOL;
+ return PG_TYPE_BOOL;
case Types.VARCHAR:
- return PG_TYPE_VARCHAR;
- case Types.CLOB:
- return PG_TYPE_TEXT;
+ return PG_TYPE_VARCHAR;
case Types.CHAR:
- return PG_TYPE_BPCHAR;
+ return PG_TYPE_BPCHAR;
+ case Types.TINYINT:
case Types.SMALLINT:
- return PG_TYPE_INT2;
+ return PG_TYPE_INT2;
case Types.INTEGER:
- return PG_TYPE_INT4;
+ return PG_TYPE_INT4;
case Types.BIGINT:
- return PG_TYPE_INT8;
+ return PG_TYPE_INT8;
+ case Types.NUMERIC:
case Types.DECIMAL:
- return PG_TYPE_NUMERIC;
+ return PG_TYPE_NUMERIC;
+ case Types.FLOAT:
case Types.REAL:
- return PG_TYPE_FLOAT4;
+ return PG_TYPE_FLOAT4;
case Types.DOUBLE:
return PG_TYPE_FLOAT8;
case Types.TIME:
@@ -571,14 +674,44 @@
return PG_TYPE_DATE;
case Types.TIMESTAMP:
return PG_TYPE_TIMESTAMP_NO_TMZONE;
- case Types.VARBINARY:
- return PG_TYPE_BYTEA;
- case Types.BLOB:
- return PG_TYPE_OID;
- case Types.ARRAY:
- return PG_TYPE_TEXTARRAY;
+
+ 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;
}
}
+
+ private static final byte[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e','f' };
+
+ /**
+ * When sending the byteA content to client convert into Hex before sending the content.
+ * @param b
+ * @return
+ * @throws IOException
+ */
+ static byte[] toHex(byte[] b) throws IOException {
+ byte[] hexbytes = PgFrontendProtocol.createByteArray((2 * b.length)+2);
+ hexbytes[0] = '\\';
+ hexbytes[1] = 'x';
+
+ for (int i = 0; i < b.length; i++) {
+ int index = (i*2)+2;
+ int v = b[i] & 0xff;
+ hexbytes[index] = hexChars[v >> 4];
+ hexbytes[index+1] = hexChars[v & 0xf];
+ }
+ return hexbytes;
+ }
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -47,6 +47,15 @@
@SuppressWarnings("nls")
public class PgFrontendProtocol extends FrameDecoder {
+ private static final int LO_CREAT = 957;
+ private static final int LO_OPEN = 952;
+ private static final int LO_CLOSE = 953;
+ private static final int LO_READ = 954;
+ private static final int LO_WRITE = 955;
+ private static final int LO_LSEEK = 956;
+ private static final int LO_TELL = 958;
+ private static final int LO_UNLINK = 964;
+
private int maxObjectSize;
private Byte messageType;
private Integer dataLength;
@@ -148,7 +157,9 @@
case 'C':
return buildClose(data);
case 'H':
- return buildFlush();
+ return buildFlush();
+ case 'F':
+ return buildFunctionCall(data);
default:
return buildError();
}
@@ -179,6 +190,13 @@
int version = data.readInt();
props.setProperty("version", Integer.toString(version));
+ // SSL Request
+ if (version == 80877103) {
+ this.initialized = false;
+ this.odbcProxy.sslRequest();
+ return message;
+ }
+
trace("StartupMessage");
trace(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")");
@@ -235,7 +253,7 @@
}
int paramCount = data.readShort();
- Object[] params = new String[paramCount];
+ Object[] params = new Object[paramCount];
for (int i = 0; i < paramCount; i++) {
int paramLen = data.readInt();
byte[] paramdata = createByteArray(paramLen);
@@ -299,7 +317,7 @@
return message;
}
- private byte[] createByteArray(int length) throws StreamCorruptedException{
+ static byte[] createByteArray(int length) throws StreamCorruptedException{
try {
return new byte[length];
} catch(OutOfMemoryError e) {
@@ -322,6 +340,66 @@
return message;
}
+ /**
+ * LO functions are always binary, so I am ignoring the formats, return types. The below is not used
+ * leaving for future if ever LO is revisited
+ */
+ @SuppressWarnings("unused")
+ private Object buildFunctionCall(NullTerminatedStringDataInputStream data) throws IOException {
+ int funcID = data.readInt();
+
+ // read data types of arguments
+ int formatCount = data.readShort();
+ int[] formatTypes = new int[formatCount];
+ for (int i = 0; i< formatCount; i++) {
+ formatTypes[i] = data.readShort();
+ }
+
+ // arguments
+ data.readShort(); // ignore the param count; we know them by functions supported.
+ int oid = readInt(data);
+ switch(funcID) {
+ case LO_CREAT:
+ break;
+ case LO_OPEN:
+ int mode = readInt(data);
+ break;
+ case LO_CLOSE:
+ break;
+ case LO_READ:
+ int length = readInt(data);
+ break;
+ case LO_WRITE:
+ byte[] contents = readByteArray(data);
+ break;
+ case LO_LSEEK:
+ int offset = readInt(data);
+ int where = readInt(data);
+ break;
+ case LO_TELL:
+ break;
+ case LO_UNLINK:
+ break;
+ }
+ this.odbcProxy.functionCall(oid);
+ return message;
+ }
+
+ private int readInt(NullTerminatedStringDataInputStream data) throws IOException {
+ data.readInt(); // ignore this this is length always 4
+ return data.readInt();
+ }
+
+ private byte[] readByteArray(NullTerminatedStringDataInputStream data) throws IOException {
+ int length = data.readInt();
+ if (length == -1 || length == 0) {
+ return null;
+ }
+ byte[] content = createByteArray(length);
+ data.read(content, 0, length);
+ return content;
+ }
+
static class NullTerminatedStringDataInputStream extends DataInputStream{
private String encoding;
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-02-14 01:30:06 UTC (rev 2904)
@@ -87,3 +87,4 @@
error_closing_stmt=Error closing portal statement {0}
model_metadata_loading=VDB "{0}" - "{1}" model metadata is currently being loaded. Start Time: {2}
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
\ No newline at end of file
14 years, 10 months
teiid SVN: r2903 - in trunk: api/src/main/java/org/teiid/translator and 21 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-10 14:56:37 -0500 (Thu, 10 Feb 2011)
New Revision: 2903
Added:
trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java
trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java
Removed:
trunk/engine/src/main/resources/org/teiid/query/execution/
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
Log:
TEIID-1011 TEIID-247 refining the mondrian/olap support to use a more efficient array based processing and adding system functions to handle array values
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -103,6 +103,8 @@
public static final String ENCODING = "ENCODING"; //$NON-NLS-1$
public static final String TEXTAGG = "TEXTAGG"; //$NON-NLS-1$
+
+ public static final String ARRAYTABLE = "ARRAYTABLE"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -133,6 +133,8 @@
public static final String IFNULL = "ifnull"; //$NON-NLS-1$
public static final String COALESCE = "coalesce"; //$NON-NLS-1$
public static final String NULLIF = "nullif"; //$NON-NLS-1$
+ public static final String ARRAY_GET = "array_get"; //$NON-NLS-1$
+ public static final String ARRAY_LENGTH = "array_length"; //$NON-NLS-1$
//conversion functions
public static final String CONVERT = "convert"; //$NON-NLS-1$
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-10 19:56:37 UTC (rev 2903)
@@ -29,7 +29,13 @@
<LI><B>Virtual procedure out params</B> - virtual procedures can now have RETURN/OUT/INOUT parameters to return values.
<LI><B>OLAP</B> - OLAP translator is now part of Teiid kit using OLAP4J
<LI><B>Multi-source procedures</B> - multi-source handling was expanded to cover stored procedure execution. See the Reference for more.
- <LI><B>UUID function</B> - was added to generate type 4 UUIDs and the Hibernate dialect was updated to support the GUIDGenerator.
+ <LI><B>Function Support</B> - additional system functions were made available.
+ <UL>
+ <LI><B>uuid</B> was added to generate type 4 UUIDs and the Hibernate dialect was updated to support the GUIDGenerator.
+ <LI><B>array_get</B> was added to extract values from java.sql.Array or java array values.
+ <LI><B>array_length</B> was added to get the length of java.sql.Array or java array values.
+ </UL>
+ <LI><B>ARRAYTABLE</B> - the ARRAYTABLE table function was added to simplify array value extraction into a tabular format.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -89,7 +89,7 @@
"PARSETIMESTAMP, QUARTER, SECOND, TIMESTAMPADD, TIMESTAMPDIFF, WEEK, YEAR"; //$NON-NLS-1$
// constant value giving the names of system functions supported
final static String SYSTEM_FUNCTIONS =
- "CAST, COALESCE, CONVERT, DECODESTRING, DECODEINTEGER, IFNULL, NULLIF, NVL, LOOKUP"; //$NON-NLS-1$
+ "CAST, COALESCE, CONVERT, DECODESTRING, DECODEINTEGER, IFNULL, NULLIF, NVL, LOOKUP, UUID, UNESCAPE, ARRAY_GET, ARRAY_LENGTH"; //$NON-NLS-1$
// constant value giving max length of a catalog name
private final static int MAX_CATALOG_NAME_LENGTH = 255;
// constant value giving max length of a procedure name
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -57,8 +57,7 @@
ProcedureParameter param = metadataFactory.addProcedureParameter("request", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The MDX query to execute"); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
-
- metadataFactory.addProcedureParameter("result", TypeFacility.RUNTIME_NAMES.XML, Type.ReturnValue, p); //$NON-NLS-1$
+ metadataFactory.addProcedureResultSetColumn("tuple", TypeFacility.RUNTIME_NAMES.OBJECT, p); //$NON-NLS-1$
}
@Override
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -21,16 +21,11 @@
*/
package org.teiid.translator.olap;
-import java.io.IOException;
-import java.io.Reader;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.olap4j.Axis;
import org.olap4j.Cell;
import org.olap4j.CellSet;
@@ -48,6 +43,9 @@
import org.teiid.translator.ProcedureExecution;
import org.teiid.translator.TranslatorException;
+/**
+ * Executes the given MDX and packs the results into an array
+ */
public class OlapQueryExecution implements ProcedureExecution {
protected Command command;
@@ -55,8 +53,10 @@
protected ExecutionContext context;
protected OlapExecutionFactory executionFactory;
private OlapStatement stmt;
- private Source returnValue;
-
+ private CellSet cellSet;
+ private CellSetAxis cols;
+ private int colWidth;
+ private ListIterator<Position> iterator;
public OlapQueryExecution(Command command, OlapConnection connection, ExecutionContext context, OlapExecutionFactory executionFactory) {
this.command = command;
@@ -71,12 +71,13 @@
Call procedure = (Call) this.command;
List<Argument> arguments = procedure.getArguments();
String mdxQuery = (String) arguments.get(0).getArgumentValue().getValue();
- OlapStatement stmt = this.connection.createStatement();
+ stmt = this.connection.createStatement();
- CellSet cellSet = stmt.executeOlapQuery(mdxQuery);
- this.returnValue = new StreamSource(new MdxResultsReader(cellSet));
-
-
+ cellSet = stmt.executeOlapQuery(mdxQuery);
+ CellSetAxis rows = this.cellSet.getAxes().get(Axis.ROWS.axisOrdinal());
+ iterator = rows.iterator();
+ cols = cellSet.getAxes().get(Axis.COLUMNS.axisOrdinal());
+ colWidth = rows.getAxisMetaData().getHierarchies().size() + this.cols.getPositions().size();
} catch (SQLException e) {
throw new TranslatorException(e);
}
@@ -85,8 +86,9 @@
@Override
public void cancel() throws TranslatorException {
try {
- if (this.stmt != null) {
- this.stmt.cancel();
+ OlapStatement olapStatement = this.stmt;
+ if (olapStatement != null) {
+ olapStatement.cancel();
}
} catch (SQLException e) {
throw new TranslatorException(e);
@@ -94,7 +96,7 @@
}
@Override
- public synchronized void close() {
+ public void close() {
try {
if (this.stmt != null) {
this.stmt.close();
@@ -107,100 +109,30 @@
@Override
public List<?> next() throws TranslatorException {
- return null;
+ if (!iterator.hasNext()) {
+ return null;
+ }
+ Position nextRow = iterator.next();
+ Object[] result = new Object[colWidth];
+ int i = 0;
+ // add in rows axis
+ List<Member> members = nextRow.getMembers();
+ for (Member member:members) {
+ String columnName = member.getHierarchy().getName();
+ result[i++] = columnName;
+ }
+
+ // add col axis
+ for (Position colPos : cols) {
+ Cell cell = cellSet.getCell(colPos, nextRow);
+ result[i++] = cell.getValue();
+ }
+ return Arrays.asList(result);
}
@Override
public List<?> getOutputParameterValues() throws TranslatorException {
- return Arrays.asList(this.returnValue);
+ return null;
}
- static class MdxResultsReader extends Reader {
- private CellSet cellSet;
- private ListIterator<Position> rows;
- private Position nextRow;
- private boolean closed = false;
- private char[] buffer;
- private int index = 0;
-
- public MdxResultsReader(CellSet cellSet) {
- this.cellSet = cellSet;
- CellSetAxis rowAxis = cellSet.getAxes().get(Axis.ROWS.axisOrdinal());
- this.rows = rowAxis.iterator();
- if (this.rows.hasNext()) {
- this.nextRow = this.rows.next();
- this.buffer = "<resultset>".toCharArray(); //$NON-NLS-1$
- }
- }
-
- private String readNextRow() {
- if (this.nextRow == null) {
- return null;
- }
-
- StringBuilder sb = new StringBuilder();
- CellSetAxis cols = cellSet.getAxes().get(Axis.COLUMNS.axisOrdinal());
- sb.append("<row>"); //$NON-NLS-1$
-
- // add in rows axis
- List<Member> members = nextRow.getMembers();
- for (Member member:members) {
- String columnName = member.getHierarchy().getName();
- columnName = columnName.replace(' ', '_');
- sb.append('<').append(columnName).append('>');
- sb.append(member.getName());
- sb.append("</").append(columnName).append('>'); //$NON-NLS-1$
- }
-
- // add col axis
- for (Position colPos : cols) {
- Cell cell = cellSet.getCell(colPos, nextRow);
- String columnName = colPos.getMembers().get(0).getName();
- columnName = columnName.replace(' ', '_');
- sb.append('<').append(columnName).append('>');
- sb.append(cell.getValue());
- sb.append("</").append(columnName).append('>'); //$NON-NLS-1$
- }
- sb.append("</row>");//$NON-NLS-1$
-
- // advance the cursor to next row.
- if (this.rows.hasNext()) {
- this.nextRow = this.rows.next();
- }
- else {
- this.nextRow = null;
- }
- return sb.toString();
- }
-
- @Override
- public void close() throws IOException {
- }
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- int availble = this.buffer.length - this.index;
- if (availble == 0) {
- String next = readNextRow();
- if (next == null) {
- if (!this.closed) {
- this.buffer = "</resultset>".toCharArray();//$NON-NLS-1$
- this.closed = true;
- }
- else {
- return -1;
- }
- }
- else {
- this.buffer = next.toCharArray();
- }
- this.index = 0;
- availble = this.buffer.length;
- }
- len = (availble > len) ? len : availble;
- System.arraycopy(this.buffer, this.index, cbuf, off, len);
- this.index = this.index + len;
- return len;
- }
- }
}
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -508,7 +508,7 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod39" xreflabel="createElementsWithTypes"/>createElementsWithTypes</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( <COMMA> <link linkend="prod2">id</link> <link linkend="prod35">dataType</link> )*</para></entry></row>
+<link linkend="prod2">id</link> <link linkend="prod19">dataTypeString</link> ( <COMMA> <link linkend="prod2">id</link> <link linkend="prod19">dataTypeString</link> )*</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod6" xreflabel="callableStatement"/>callableStatement</para></entry>
<entry align="left" valign="top"><para>::=
@@ -628,9 +628,9 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod69" xreflabel="tablePrimary"/>tablePrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod72">textTable</link> | <link linkend="prod73">xmlTable</link> | <link linkend="prod74">unaryFromClause</link> | <link linkend="prod75">subqueryFromClause</link> | ( <LPAREN> <link linkend="prod68">joinedTable</link> <RPAREN> ) ) ( ( <MAKEDEP> ) | ( <MAKENOTDEP> ) )?</para></entry></row>
+( <link linkend="prod72">textTable</link> | <link linkend="prod73">arrayTable</link> | <link linkend="prod74">xmlTable</link> | <link linkend="prod75">unaryFromClause</link> | <link linkend="prod76">subqueryFromClause</link> | ( <LPAREN> <link linkend="prod68">joinedTable</link> <RPAREN> ) ) ( ( <MAKEDEP> ) | ( <MAKENOTDEP> ) )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod76" xreflabel="xmlSerialize"/>xmlSerialize</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod77" xreflabel="xmlSerialize"/>xmlSerialize</para></entry>
<entry align="left" valign="top"><para>::=
<XMLSERIALIZE> <LPAREN> ( <link linkend="prod18">nonReserved</link> )? <link linkend="prod21">expression</link> ( <AS> ( <STRING> | <VARCHAR> | <CLOB> ) )? <RPAREN></para></entry></row>
<row>
@@ -638,35 +638,39 @@
<entry align="left" valign="top"><para>::=
<ID></para></entry></row>
<row>
+<entry align="right" valign="top"><para><anchor id="prod73" xreflabel="arrayTable"/>arrayTable</para></entry>
+<entry align="left" valign="top"><para>::=
+<ID> <LPAREN> <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod39">createElementsWithTypes</link> <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
+<row>
<entry align="right" valign="top"><para><anchor id="prod72" xreflabel="textTable"/>textTable</para></entry>
<entry align="left" valign="top"><para>::=
-<ID> <LPAREN> <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod77">textColumn</link> ( <COMMA> <link linkend="prod77">textColumn</link> )* ( <ID> <link linkend="prod65">charVal</link> )? ( ( <ESCAPE> <link linkend="prod65">charVal</link> ) | ( <ID> <link linkend="prod65">charVal</link> ) )? ( <ID> ( <link linkend="prod78">intVal</link> )? )? ( <ID> <link linkend="prod78">intVal</link> )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
+<ID> <LPAREN> <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod78">textColumn</link> ( <COMMA> <link linkend="prod78">textColumn</link> )* ( <ID> <link linkend="prod65">charVal</link> )? ( ( <ESCAPE> <link linkend="prod65">charVal</link> ) | ( <ID> <link linkend="prod65">charVal</link> ) )? ( <ID> ( <link linkend="prod79">intVal</link> )? )? ( <ID> <link linkend="prod79">intVal</link> )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod77" xreflabel="textColumn"/>textColumn</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod78" xreflabel="textColumn"/>textColumn</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( <ID> <link linkend="prod78">intVal</link> )?</para></entry></row>
+<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( <ID> <link linkend="prod79">intVal</link> )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod79" xreflabel="xmlQuery"/>xmlQuery</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod80" xreflabel="xmlQuery"/>xmlQuery</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLQUERY> <LPAREN> ( <link linkend="prod80">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( ( <NULL> | <link linkend="prod18">nonReserved</link> ) <ON> <link linkend="prod18">nonReserved</link> )? <RPAREN></para></entry></row>
+<XMLQUERY> <LPAREN> ( <link linkend="prod81">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( ( <NULL> | <link linkend="prod18">nonReserved</link> ) <ON> <link linkend="prod18">nonReserved</link> )? <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod73" xreflabel="xmlTable"/>xmlTable</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod74" xreflabel="xmlTable"/>xmlTable</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLTABLE> <LPAREN> ( <link linkend="prod80">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( <ID> <link linkend="prod81">xmlColumn</link> ( <COMMA> <link linkend="prod81">xmlColumn</link> )* )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
+<XMLTABLE> <LPAREN> ( <link linkend="prod81">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( <ID> <link linkend="prod82">xmlColumn</link> ( <COMMA> <link linkend="prod82">xmlColumn</link> )* )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod81" xreflabel="xmlColumn"/>xmlColumn</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod82" xreflabel="xmlColumn"/>xmlColumn</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod2">id</link> ( ( <FOR> <link linkend="prod18">nonReserved</link> ) | ( <link linkend="prod35">dataType</link> ( <DEFAULT_KEYWORD> <link linkend="prod21">expression</link> )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod1">stringVal</link> )? ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod78" xreflabel="intVal"/>intVal</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod79" xreflabel="intVal"/>intVal</para></entry>
<entry align="left" valign="top"><para>::=
<INTEGERVAL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod75" xreflabel="subqueryFromClause"/>subqueryFromClause</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod76" xreflabel="subqueryFromClause"/>subqueryFromClause</para></entry>
<entry align="left" valign="top"><para>::=
( <TABLE> )? <LPAREN> ( <link linkend="prod10">queryExpression</link> | <link linkend="prod11">storedProcedure</link> ) <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod74" xreflabel="unaryFromClause"/>unaryFromClause</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod75" xreflabel="unaryFromClause"/>unaryFromClause</para></entry>
<entry align="left" valign="top"><para>::=
( <ID> ( ( <AS> )? <link linkend="prod2">id</link> )? )</para></entry></row>
<row>
@@ -676,69 +680,69 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod32" xreflabel="criteria"/>criteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod82">compoundCritOr</link></para></entry></row>
+<link linkend="prod83">compoundCritOr</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod82" xreflabel="compoundCritOr"/>compoundCritOr</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod83" xreflabel="compoundCritOr"/>compoundCritOr</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod83">compoundCritAnd</link> ( <OR> <link linkend="prod83">compoundCritAnd</link> )*</para></entry></row>
+<link linkend="prod84">compoundCritAnd</link> ( <OR> <link linkend="prod84">compoundCritAnd</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod83" xreflabel="compoundCritAnd"/>compoundCritAnd</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod84" xreflabel="compoundCritAnd"/>compoundCritAnd</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod84">notCrit</link> ( <AND> <link linkend="prod84">notCrit</link> )*</para></entry></row>
+<link linkend="prod85">notCrit</link> ( <AND> <link linkend="prod85">notCrit</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod84" xreflabel="notCrit"/>notCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod85" xreflabel="notCrit"/>notCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <link linkend="prod85">booleanPrimary</link></para></entry></row>
+( <NOT> )? <link linkend="prod86">booleanPrimary</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod85" xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod86" xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod38">translateCriteria</link> | ( <link linkend="prod86">commonValueExpression</link> ( ( <link linkend="prod87">betweenCrit</link> | <link linkend="prod88">matchCrit</link> | <link linkend="prod89">setCrit</link> | <link linkend="prod90">isNullCrit</link> | <link linkend="prod91">subqueryCompareCriteria</link> | <link linkend="prod92">compareCrit</link> ) )? ) | <link linkend="prod93">existsCriteria</link> | <link linkend="prod34">hasCriteria</link> )</para></entry></row>
+( <link linkend="prod38">translateCriteria</link> | ( <link linkend="prod87">commonValueExpression</link> ( ( <link linkend="prod88">betweenCrit</link> | <link linkend="prod89">matchCrit</link> | <link linkend="prod90">setCrit</link> | <link linkend="prod91">isNullCrit</link> | <link linkend="prod92">subqueryCompareCriteria</link> | <link linkend="prod93">compareCrit</link> ) )? ) | <link linkend="prod94">existsCriteria</link> | <link linkend="prod34">hasCriteria</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod94" xreflabel="operator"/>operator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod95" xreflabel="operator"/>operator</para></entry>
<entry align="left" valign="top"><para>::=
( <EQ> | <NE> | <NE2> | <LT> | <LE> | <GT> | <GE> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod92" xreflabel="compareCrit"/>compareCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod93" xreflabel="compareCrit"/>compareCrit</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod94">operator</link> <link linkend="prod86">commonValueExpression</link></para></entry></row>
+<link linkend="prod95">operator</link> <link linkend="prod87">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod95" xreflabel="subquery"/>subquery</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod96" xreflabel="subquery"/>subquery</para></entry>
<entry align="left" valign="top"><para>::=
<LPAREN> ( <link linkend="prod10">queryExpression</link> | ( <link linkend="prod11">storedProcedure</link> ) ) <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod91" xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod92" xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod94">operator</link> ( <ANY> | <SOME> | <ALL> ) <link linkend="prod95">subquery</link></para></entry></row>
+<link linkend="prod95">operator</link> ( <ANY> | <SOME> | <ALL> ) <link linkend="prod96">subquery</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod88" xreflabel="matchCrit"/>matchCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod89" xreflabel="matchCrit"/>matchCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <LIKE> <link linkend="prod86">commonValueExpression</link> ( <ESCAPE> <link linkend="prod65">charVal</link> | ( <LBRACE> <ESCAPE> <link linkend="prod65">charVal</link> <RBRACE> ) )?</para></entry></row>
+( <NOT> )? <LIKE> <link linkend="prod87">commonValueExpression</link> ( <ESCAPE> <link linkend="prod65">charVal</link> | ( <LBRACE> <ESCAPE> <link linkend="prod65">charVal</link> <RBRACE> ) )?</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod65" xreflabel="charVal"/>charVal</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod87" xreflabel="betweenCrit"/>betweenCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod88" xreflabel="betweenCrit"/>betweenCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <BETWEEN> <link linkend="prod86">commonValueExpression</link> <AND> <link linkend="prod86">commonValueExpression</link></para></entry></row>
+( <NOT> )? <BETWEEN> <link linkend="prod87">commonValueExpression</link> <AND> <link linkend="prod87">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod90" xreflabel="isNullCrit"/>isNullCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod91" xreflabel="isNullCrit"/>isNullCrit</para></entry>
<entry align="left" valign="top"><para>::=
<IS> ( <NOT> )? <NULL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod89" xreflabel="setCrit"/>setCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod90" xreflabel="setCrit"/>setCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <IN> ( ( <link linkend="prod95">subquery</link> ) | ( <LPAREN> <link linkend="prod86">commonValueExpression</link> ( <COMMA> <link linkend="prod86">commonValueExpression</link> )* <RPAREN> ) )</para></entry></row>
+( <NOT> )? <IN> ( ( <link linkend="prod96">subquery</link> ) | ( <LPAREN> <link linkend="prod87">commonValueExpression</link> ( <COMMA> <link linkend="prod87">commonValueExpression</link> )* <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod93" xreflabel="existsCriteria"/>existsCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod94" xreflabel="existsCriteria"/>existsCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<EXISTS> <link linkend="prod95">subquery</link></para></entry></row>
+<EXISTS> <link linkend="prod96">subquery</link></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod57" xreflabel="groupBy"/>groupBy</para></entry>
<entry align="left" valign="top"><para>::=
-<GROUP> <BY> ( <link linkend="prod96">groupByItem</link> ( <COMMA> <link linkend="prod96">groupByItem</link> )* )</para></entry></row>
+<GROUP> <BY> ( <link linkend="prod97">groupByItem</link> ( <COMMA> <link linkend="prod97">groupByItem</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod96" xreflabel="groupByItem"/>groupByItem</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod97" xreflabel="groupByItem"/>groupByItem</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod21">expression</link></para></entry></row>
<row>
@@ -748,13 +752,13 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod50" xreflabel="orderby"/>orderby</para></entry>
<entry align="left" valign="top"><para>::=
-<ORDER> <BY> <link linkend="prod97">sortSpecification</link> ( <COMMA> <link linkend="prod97">sortSpecification</link> )*</para></entry></row>
+<ORDER> <BY> <link linkend="prod98">sortSpecification</link> ( <COMMA> <link linkend="prod98">sortSpecification</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod97" xreflabel="sortSpecification"/>sortSpecification</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod98" xreflabel="sortSpecification"/>sortSpecification</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod98">sortKey</link> ( <ASC> | <DESC> )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod18">nonReserved</link> )?</para></entry></row>
+<link linkend="prod99">sortKey</link> ( <ASC> | <DESC> )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod18">nonReserved</link> )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod98" xreflabel="sortKey"/>sortKey</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod99" xreflabel="sortKey"/>sortKey</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod21">expression</link></para></entry></row>
<row>
@@ -770,71 +774,71 @@
<entry align="left" valign="top"><para>::=
<link linkend="prod32">criteria</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod86" xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod87" xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod99">plusExpression</link> ( <CONCAT_OP> <link linkend="prod99">plusExpression</link> )* )</para></entry></row>
+( <link linkend="prod100">plusExpression</link> ( <CONCAT_OP> <link linkend="prod100">plusExpression</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod99" xreflabel="plusExpression"/>plusExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod100" xreflabel="plusExpression"/>plusExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod100">timesExpression</link> ( <link linkend="prod101">plusOperator</link> <link linkend="prod100">timesExpression</link> )* )</para></entry></row>
+( <link linkend="prod101">timesExpression</link> ( <link linkend="prod102">plusOperator</link> <link linkend="prod101">timesExpression</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod101" xreflabel="plusOperator"/>plusOperator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod102" xreflabel="plusOperator"/>plusOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <PLUS> | <MINUS> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod100" xreflabel="timesExpression"/>timesExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod101" xreflabel="timesExpression"/>timesExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod102">valueExpressionPrimary</link> ( <link linkend="prod103">timesOperator</link> <link linkend="prod102">valueExpressionPrimary</link> )* )</para></entry></row>
+( <link linkend="prod103">valueExpressionPrimary</link> ( <link linkend="prod104">timesOperator</link> <link linkend="prod103">valueExpressionPrimary</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod103" xreflabel="timesOperator"/>timesOperator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod104" xreflabel="timesOperator"/>timesOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <STAR> | <SLASH> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod102" xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod103" xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <QMARK> | <link linkend="prod104">literal</link> | ( <LBRACE> <link linkend="prod18">nonReserved</link> <link linkend="prod105">function</link> <RBRACE> ) | ( <link linkend="prod64">textAgg</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod63">xmlAgg</link> ) | ( <link linkend="prod105">function</link> ) | ( <ID> ) | <link linkend="prod95">subquery</link> | ( <LPAREN> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod106">searchedCaseExpression</link> | <link linkend="prod107">caseExpression</link> )</para></entry></row>
+( <QMARK> | <link linkend="prod105">literal</link> | ( <LBRACE> <link linkend="prod18">nonReserved</link> <link linkend="prod106">function</link> <RBRACE> ) | ( <link linkend="prod64">textAgg</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod63">xmlAgg</link> ) | ( <link linkend="prod106">function</link> ) | ( <ID> ) | <link linkend="prod96">subquery</link> | ( <LPAREN> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod107">searchedCaseExpression</link> | <link linkend="prod108">caseExpression</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod107" xreflabel="caseExpression"/>caseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod108" xreflabel="caseExpression"/>caseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> <link linkend="prod21">expression</link> ( <WHEN> <link linkend="prod21">expression</link> <THEN> <link linkend="prod21">expression</link> )+ ( <ELSE> <link linkend="prod21">expression</link> )? <END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod106" xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod107" xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> ( <WHEN> <link linkend="prod32">criteria</link> <THEN> <link linkend="prod21">expression</link> )+ ( <ELSE> <link linkend="prod21">expression</link> )? <END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod105" xreflabel="function"/>function</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod106" xreflabel="function"/>function</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <CONVERT> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <CAST> <LPAREN> <link linkend="prod21">expression</link> <AS> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod108">stringConstant</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod109">intervalType</link> <COMMA> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod110">queryString</link> | ( ( <LEFT> | <RIGHT> | <CHAR> | <USER> | <YEAR> | <MONTH> | <HOUR> | <MINUTE> | <SECOND> | <XMLCONCAT> | <XMLCOMMENT> ) <LPAREN> ( <link linkend="prod21">expression</link> !
( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <INSERT> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <TRANSLATE> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | <link linkend="prod111">xmlParse</link> | <link linkend="prod112">xmlElement</link> | ( <XMLPI> <LPAREN> ( <ID> <link linkend="prod113">idExpression</link> | <link linkend="prod113">idExpression</link> ) ( <COMMA> <link linkend="prod21">expression</link> )? <RPAREN> ) | <link linkend="prod114">xmlForest</link> | <link linkend="prod76">xmlSerialize</link> | <link linkend="prod79">xmlQuery</link> | ( <link linkend="prod2">id</link> <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )*!
)? <RPAREN> ) )</para></entry></row>
+( ( <CONVERT> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <CAST> <LPAREN> <link linkend="prod21">expression</link> <AS> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod109">stringConstant</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod110">intervalType</link> <COMMA> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod111">queryString</link> | ( ( <LEFT> | <RIGHT> | <CHAR> | <USER> | <YEAR> | <MONTH> | <HOUR> | <MINUTE> | <SECOND> | <XMLCONCAT> | <XMLCOMMENT> ) <LPAREN> ( <link linkend="prod21">expression</link> !
( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <INSERT> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <TRANSLATE> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | <link linkend="prod112">xmlParse</link> | <link linkend="prod113">xmlElement</link> | ( <XMLPI> <LPAREN> ( <ID> <link linkend="prod114">idExpression</link> | <link linkend="prod114">idExpression</link> ) ( <COMMA> <link linkend="prod21">expression</link> )? <RPAREN> ) | <link linkend="prod115">xmlForest</link> | <link linkend="prod77">xmlSerialize</link> | <link linkend="prod80">xmlQuery</link> | ( <link linkend="prod2">id</link> <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )*!
)? <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod108" xreflabel="stringConstant"/>stringConstant</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod109" xreflabel="stringConstant"/>stringConstant</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod111" xreflabel="xmlParse"/>xmlParse</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod112" xreflabel="xmlParse"/>xmlParse</para></entry>
<entry align="left" valign="top"><para>::=
<XMLPARSE> <LPAREN> <link linkend="prod18">nonReserved</link> <link linkend="prod21">expression</link> ( <link linkend="prod18">nonReserved</link> )? <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod110" xreflabel="queryString"/>queryString</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod111" xreflabel="queryString"/>queryString</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod112" xreflabel="xmlElement"/>xmlElement</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod113" xreflabel="xmlElement"/>xmlElement</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLELEMENT> <LPAREN> ( <ID> <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( <COMMA> <link linkend="prod80">xmlNamespaces</link> )? ( <COMMA> <link linkend="prod115">xmlAttributes</link> )? ( <COMMA> <link linkend="prod21">expression</link> )* <RPAREN></para></entry></row>
+<XMLELEMENT> <LPAREN> ( <ID> <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( <COMMA> <link linkend="prod81">xmlNamespaces</link> )? ( <COMMA> <link linkend="prod116">xmlAttributes</link> )? ( <COMMA> <link linkend="prod21">expression</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod115" xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod116" xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
<entry align="left" valign="top"><para>::=
<XMLATTRIBUTES> <LPAREN> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod114" xreflabel="xmlForest"/>xmlForest</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod115" xreflabel="xmlForest"/>xmlForest</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLFOREST> <LPAREN> ( <link linkend="prod80">xmlNamespaces</link> <COMMA> )? <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
+<XMLFOREST> <LPAREN> ( <link linkend="prod81">xmlNamespaces</link> <COMMA> )? <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod80" xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod81" xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLNAMESPACES> <LPAREN> <link linkend="prod116">namespaceItem</link> ( <COMMA> <link linkend="prod116">namespaceItem</link> )* <RPAREN></para></entry></row>
+<XMLNAMESPACES> <LPAREN> <link linkend="prod117">namespaceItem</link> ( <COMMA> <link linkend="prod117">namespaceItem</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod116" xreflabel="namespaceItem"/>namespaceItem</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod117" xreflabel="namespaceItem"/>namespaceItem</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> <AS> <link linkend="prod2">id</link> )</para></entry></row>
<row>
@@ -846,7 +850,7 @@
<entry align="left" valign="top"><para>::=
( <DEFAULT_KEYWORD> <link linkend="prod1">stringVal</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod113" xreflabel="idExpression"/>idExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod114" xreflabel="idExpression"/>idExpression</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod2">id</link></para></entry></row>
<row>
@@ -858,11 +862,11 @@
<entry align="left" valign="top"><para>::=
<link linkend="prod19">dataTypeString</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod109" xreflabel="intervalType"/>intervalType</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod110" xreflabel="intervalType"/>intervalType</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod18">nonReserved</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod104" xreflabel="literal"/>literal</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod105" xreflabel="literal"/>literal</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> | <INTEGERVAL> | <FLOATVAL> | <FALSE> | <TRUE> | <UNKNOWN> | <NULL> | ( ( <BOOLEANTYPE> | <TIMESTAMPTYPE> | <DATETYPE> | <TIMETYPE> ) <link linkend="prod1">stringVal</link> <RBRACE> ) )</para></entry></row>
</tbody>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -42,7 +42,7 @@
</entry>
<entry>
<para>x in {integer, long, float, double, biginteger,
- bigdecimal}, return type is same as x <footnote>The precision and scale of non-bigdecimal arithmetic function functions results matches that of Java. The results of bigdecimal operations match Java, except for division, which uses a preferred scale of max(16, dividend.scale + divisor.precision + 1), which then has trailing zeros removed by setting the scale to max(dividend.scale, normalized scale)</footnote></para>
+ bigdecimal}, return type is same as x <footnote><para>The precision and scale of non-bigdecimal arithmetic function functions results matches that of Java. The results of bigdecimal operations match Java, except for division, which uses a preferred scale of max(16, dividend.scale + divisor.precision + 1), which then has trailing zeros removed by setting the scale to max(dividend.scale, normalized scale)</para></footnote></para>
</entry>
</row>
<row>
@@ -2077,7 +2077,21 @@
<section>
<title>Miscellaneous Functions</title>
<para>Other functions.</para>
+ <section id="array_get">
+ <title>array_get</title>
+ <para>Retuns the object value at a given array index.</para>
+ <para><synopsis>array_get(array, index)</synopsis></para>
+ <para>array is the object type, index must be an integer, and the return type is object.</para>
+ <para>1-based indexing is used. The actual array value should be a java.sql.Array or java array type. An exception will be thrown if the array value is the wrong type of the index is out of bounds.</para>
+ </section>
<section>
+ <title>array_length</title>
+ <para>Returns the length for a given array</para>
+ <para><synopsis>array_length(array)</synopsis></para>
+ <para>array is the object type, and the return type is integer.</para>
+ <para>The actual array value should be a java.sql.Array or java array type. An exception will be thrown if the array value is the wrong type.</para>
+ </section>
+ <section>
<title>uuid</title>
<para>Retuns a universally unique identifier.</para>
<para><synopsis>uuid()</synopsis></para>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -799,6 +799,7 @@
<listitem><para>FROM table1 left outer join <link linkend="optional_join">/*+ optional */</link> table2 ON join-criteria</para></listitem>
<listitem><para>FROM <link linkend="texttable">TEXTTABLE...</link></para></listitem>
<listitem><para>FROM <link linkend="xmltable">XMLTABLE...</link></para></listitem>
+ <listitem><para>FROM <link linkend="arraytable">ARRAYTABLE...</link></para></listitem>
</itemizedlist>
<note>
<title>DEP Hints</title>
@@ -966,6 +967,41 @@
</itemizedlist>
</section>
</section>
+ <section id="arraytable">
+ <title>ARRAYTABLE</title>
+ <para>The ARRAYTABLE funciton processes an array input to produce tabular ouptut.
+ The function itself defines what columns it projects.
+ The ARRAYTABLE function is implicitly a nested table and may be correlated to preceeding FROM clause entries.
+ </para>
+ <para>
+ Usage:
+ <synopsis label="Usage">ARRAYTABLE(expression COLUMNS <COLUMN>, ...) AS name</synopsis>
+ <synopsis label="Usage">COLUMN := name datatype</synopsis>
+ </para>
+ <itemizedlist>
+ <para>Parameters</para>
+ <listitem>
+ <para>expression - the array to process, which should be a java.sql.Array or java array value.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <para>Syntax Rules:
+ </para>
+ <listitem>
+ <para>The columns names must be not contain duplicates.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <para>Examples</para>
+ <listitem>
+ <para>As a nested table: <programlisting>select x.* from (call source.invokeMDX('some query')) r, arraytable(r.tuple COLUMNS first string, second bigdecimal) x</programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>ARRAYTABLE is effectively a shortcut for using the <xref linkend="array_get"/> function in a nested table. For example "ARRAYGET(val COLUMNS col1 string, col2 integer) AS X" is the same as "TABLE(SELECT cast(array_get(val, 1) AS string) AS col1, cast(array_get(val, 2) AS integer) AS col2) AS X".</para>
+ </section>
<section id="where_clause">
<title>WHERE Clause</title>
<para>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -1019,16 +1019,14 @@
<title>OLAP Translator</title>
<para>
The OLAP Services translator, known by the type name <emphasis>olap</emphasis>,
- exposes stored procedures for calling analysis sevices backed by a OLAP server using MDX query lanaguage. Given the MDX
- query, this translator executes the query and returns the results in XML format.
- It will commonly be used with the <link linkend="xmltable">XMLTABLE</link> table functions to use XML formated data.
+ exposes stored procedures for calling analysis sevices backed by a OLAP server using MDX query lanaguage.
+ This translator exposes a stored procedure, invokeMDX, that returns a result set containing tuple array values for a given MDX query.
+ invokeMDX will commonly be used with the <link linkend="arraytable">ARRAYTABLE</link> table function to extract the results.
</para>
<para>
Since the Cube metadata exposed by the OLAP servers and relational database metadata are so different, there is no single
- way to map the metadata from one to other. It is best that OLAP system be queried using its own native MDX language
- through Teiid abstraction layers than introducing a custom Teiid based MDX like extensions for querying. To build MDX
- queries dynamically use Teiid's abstraction layer define your target schema in relational terms and use Teiid's procedural
- langaugage to build a query.
+ way to map the metadata from one to other. It is best to query OLAP system using its own native MDX language
+ through. MDX queries my be defined statically or built dynamically in Teiid's abstraction layers.
</para>
<section>
@@ -1040,32 +1038,17 @@
<section>
<title>InvokeMDX Procedure</title>
<para>
- <methodname>invokeMdx</methodname> returns the XML contents of results in tabular form.
+ <methodname>invokeMdx</methodname> returns a resultset of the tuples as array values.
</para>
- <programlisting>Procedure invokeMdx(mdx in STRING) returns SQLXML</programlisting>
+ <programlisting>Procedure invokeMdx(mdx in STRING) returns resultset (tuple object)</programlisting>
<para>
- mdx parameter indicates the query in its original form that is to be executed on the OLAP server.
+ The mdx parameter is a MDX query to be executed on the OLAP server.
</para>
<para>
- The results of the query will be returned in SQLXML form that in the format as shown below.
- <programlisting role="XML" language="XML"><![CDATA[
- <?xml version="1.0" encoding="UTF-8"?>
- <resultset>
- <row>
- <Promotion_Media>All Media</Promotion_Media>
- <Product>All Products</Product>
- <Unit_Sales>266773.0</Unit_Sales>
- <Store_Cost>225627.2336</Store_Cost>
- <Store_Sales>565238.13</Store_Sales>
- </row>
- </resultset>
- ]]></programlisting>
- From the above XML result, the first two columns in the row were the members from the row axis and the
- last three columns are the measures from the cube from column axis. Currently the resultset only supports
- 2 dimentional cube.
+ The results of the query will be returned such that each row on the row axis will be packed into an array value that will first contain each hierarcy member name on the row axis then each measure value from the column axis.
</para>
-
+ <note><para>Currently the resultset only supports 2 dimentional cube.</para></note>
<para>
This translator requires a data source to be configured to the OLAP cube using OLAP4J JDBC driver. Two sample
-ds.xml files provided for accessing OLAP servers in teiid-examples section. One is Mondrian specific, when Mondrian server is deloyed
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -100,7 +100,7 @@
if (!proc.isCallableStatement()) {
return;
}
- List values = requestMsg.getParameterValues();
+ List<?> values = requestMsg.getParameterValues();
List<SPParameter> spParams = proc.getParameters();
proc.clearParameters();
int inParameterCount = values.size();
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -25,12 +25,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.sql.Blob;
import java.sql.Clob;
+import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
@@ -1380,4 +1382,28 @@
return UUID.randomUUID().toString();
}
+ public static Object array_get(Object array, int index) throws FunctionExecutionException, SQLException {
+ try {
+ if (array.getClass().isArray()) {
+ return Array.get(array, index - 1);
+ }
+ if (array instanceof java.sql.Array) {
+ return Array.get(((java.sql.Array)array).getArray(index, 1), 0);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.array_index", index)); //$NON-NLS-1$
+ }
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.not_array_value", array.getClass())); //$NON-NLS-1$
+ }
+
+ public static int array_length(Object array) throws FunctionExecutionException, SQLException {
+ if (array.getClass().isArray()) {
+ return Array.getLength(array);
+ }
+ if (array instanceof java.sql.Array) {
+ return Array.getLength(((java.sql.Array)array).getArray());
+ }
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.not_array_value", array.getClass())); //$NON-NLS-1$
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -194,14 +194,30 @@
addUnescape();
addUuidFunction();
+ addArrayGet();
+ addArrayLength();
}
- private void addUnescape() {
+ private void addArrayLength() {
+ functions.add(new FunctionMethod(SourceSystemFunctions.ARRAY_LENGTH, QueryPlugin.Util.getString("SystemSource.array_length_desc"), MISCELLANEOUS, PushDown.CAN_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.ARRAY_LENGTH, //$NON-NLS-1$
+ new FunctionParameter[] {
+ new FunctionParameter("array", DataTypeManager.DefaultDataTypes.OBJECT, QueryPlugin.Util.getString("SystemSource.array_param1"))}, //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER, QueryPlugin.Util.getString("SystemSource.array_length_result")), false, Determinism.DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private void addArrayGet() {
+ functions.add(new FunctionMethod(SourceSystemFunctions.ARRAY_GET, QueryPlugin.Util.getString("SystemSource.array_get_desc"), MISCELLANEOUS, PushDown.CAN_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.ARRAY_GET, //$NON-NLS-1$
+ new FunctionParameter[] {
+ new FunctionParameter("array", DataTypeManager.DefaultDataTypes.OBJECT, QueryPlugin.Util.getString("SystemSource.array_param1")), //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("index", DataTypeManager.DefaultDataTypes.INTEGER, QueryPlugin.Util.getString("SystemSource.array_get_param2"))}, //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.OBJECT, QueryPlugin.Util.getString("SystemSource.array_get_result")), false, Determinism.DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private void addUnescape() {
functions.add(new FunctionMethod(SourceSystemFunctions.UNESCAPE, QueryPlugin.Util.getString("SystemSource.unescape_desc"), STRING, PushDown.CANNOT_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.UNESCAPE, //$NON-NLS-1$
new FunctionParameter[] {
new FunctionParameter("string", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.unescape_param1"))}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.unescape_result")), false, Determinism.DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
-
}
private void addSecurityFunctions() {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -24,7 +24,6 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -50,6 +49,7 @@
import org.teiid.query.optimizer.relational.rules.FrameUtil;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.relational.AccessNode;
+import org.teiid.query.processor.relational.ArrayTableNode;
import org.teiid.query.processor.relational.DependentAccessNode;
import org.teiid.query.processor.relational.DependentProcedureAccessNode;
import org.teiid.query.processor.relational.DependentProcedureExecutionNode;
@@ -76,6 +76,7 @@
import org.teiid.query.processor.relational.MergeJoinStrategy.SortOption;
import org.teiid.query.processor.relational.SortUtility.Mode;
import org.teiid.query.resolver.util.ResolverUtil;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.Insert;
@@ -408,6 +409,14 @@
processNode = ttn;
break;
}
+ if (source instanceof ArrayTable) {
+ ArrayTableNode atn = new ArrayTableNode(getID());
+ ArrayTable at = (ArrayTable)source;
+ updateGroupName(node, at);
+ atn.setTable(at);
+ processNode = atn;
+ break;
+ }
return null;
case NodeConstants.Types.SET_OP:
Operation setOp = (Operation) node.getProperty(NodeConstants.Info.SET_OPERATION);
Added: trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -0,0 +1,123 @@
+/*
+ * 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.processor.relational;
+
+import java.lang.reflect.Array;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+
+import org.teiid.api.exception.query.FunctionExecutionException;
+import org.teiid.common.buffer.BlockedException;
+import org.teiid.common.buffer.BufferManager;
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.TransformationException;
+import org.teiid.query.QueryPlugin;
+import org.teiid.query.processor.ProcessorDataManager;
+import org.teiid.query.sql.lang.ArrayTable;
+import org.teiid.query.sql.lang.TableFunctionReference.ProjectedColumn;
+import org.teiid.query.util.CommandContext;
+
+/**
+ * Handles array table processing.
+ */
+public class ArrayTableNode extends SubqueryAwareRelationalNode {
+
+ private ArrayTable table;
+
+ //initialized state
+ private int[] projectionIndexes;
+
+ public ArrayTableNode(int nodeID) {
+ super(nodeID);
+ }
+
+ @Override
+ public void initialize(CommandContext context, BufferManager bufferManager,
+ ProcessorDataManager dataMgr) {
+ super.initialize(context, bufferManager, dataMgr);
+ if (projectionIndexes != null) {
+ return;
+ }
+ Map elementMap = createLookupMap(table.getProjectedSymbols());
+ this.projectionIndexes = getProjectionIndexes(elementMap, getElements());
+ }
+
+ @Override
+ public void closeDirect() {
+ super.closeDirect();
+ reset();
+ }
+
+ public void setTable(ArrayTable table) {
+ this.table = table;
+ }
+
+ @Override
+ public ArrayTableNode clone() {
+ ArrayTableNode clone = new ArrayTableNode(getID());
+ this.copy(this, clone);
+ clone.setTable(table);
+ return clone;
+ }
+
+ @Override
+ protected TupleBatch nextBatchDirect() throws BlockedException,
+ TeiidComponentException, TeiidProcessingException {
+ ArrayList<Object> tuple = new ArrayList<Object>(projectionIndexes.length);
+
+ Object array = getEvaluator(Collections.emptyMap()).evaluate(table.getArrayValue(), null);
+
+ if (!array.getClass().isArray()) {
+ if (array instanceof java.sql.Array) {
+ try {
+ array = ((java.sql.Array)array).getArray();
+ } catch (SQLException e) {
+ throw new TeiidProcessingException(e);
+ }
+ } else {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.not_array_value", array.getClass())); //$NON-NLS-1$
+ }
+ }
+
+ for (int output : projectionIndexes) {
+ ProjectedColumn col = table.getColumns().get(output);
+ try {
+ Object val = Array.get(array, output);
+ tuple.add(DataTypeManager.transformValue(val, table.getColumns().get(output).getSymbol().getType()));
+ } catch (TransformationException e) {
+ throw new TeiidProcessingException(e, QueryPlugin.Util.getString("ArrayTableNode.conversion_error", col.getName())); //$NON-NLS-1$
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.array_index", output + 1)); //$NON-NLS-1$
+ }
+ }
+ addBatchRow(tuple);
+ terminateBatches();
+ return pullBatch();
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -52,6 +52,7 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.ExistsCriteria;
import org.teiid.query.sql.lang.From;
@@ -345,6 +346,13 @@
}
@Override
+ public void visit(ArrayTable obj) {
+ LinkedHashSet<GroupSymbol> saved = preTableFunctionReference(obj);
+ visitNode(obj.getArrayValue());
+ postTableFunctionReference(obj, saved);
+ }
+
+ @Override
public void visit(XMLTable obj) {
LinkedHashSet<GroupSymbol> saved = preTableFunctionReference(obj);
visitNodes(obj.getPassing());
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -76,6 +76,7 @@
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.LanguageObject.Util;
import org.teiid.query.sql.lang.AbstractSetCriteria;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.BatchedUpdateCommand;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.Command;
@@ -1039,6 +1040,9 @@
XMLTable xt = (XMLTable)clause;
xt.rewriteDefaultColumn();
rewriteExpressions(clause);
+ } else if (clause instanceof ArrayTable) {
+ ArrayTable at = (ArrayTable)clause;
+ at.setArrayValue(rewriteExpressionDirect(at.getArrayValue()));
}
return clause;
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -139,4 +139,5 @@
public void visit(ExpressionCriteria obj) {}
public void visit(WithQueryCommand obj) {}
public void visit(TriggerAction obj) {}
+ public void visit(ArrayTable obj) {}
}
Added: trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -0,0 +1,85 @@
+/*
+ * 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.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.symbol.Expression;
+
+/**
+ * Represents the ArrayTable table function.
+ */
+public class ArrayTable extends TableFunctionReference {
+
+ private Expression arrayValue;
+ private List<ProjectedColumn> columns = new ArrayList<ProjectedColumn>();
+
+ public List<ProjectedColumn> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List<ProjectedColumn> columns) {
+ this.columns = columns;
+ }
+
+ public Expression getArrayValue() {
+ return arrayValue;
+ }
+
+ public void setArrayValue(Expression arrayValue) {
+ this.arrayValue = arrayValue;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public ArrayTable clone() {
+ ArrayTable clone = new ArrayTable();
+ this.copy(clone);
+ clone.setArrayValue((Expression)this.arrayValue.clone());
+ for (ProjectedColumn column : columns) {
+ clone.getColumns().add(column.copyTo(new ProjectedColumn()));
+ }
+ return clone;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!super.equals(obj) || !(obj instanceof ArrayTable)) {
+ return false;
+ }
+ ArrayTable other = (ArrayTable)obj;
+ return this.columns.equals(other.columns)
+ && EquivalenceUtil.areEqual(arrayValue, other.arrayValue);
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -80,10 +80,11 @@
return symbol.hashCode();
}
- public void copy(ProjectedColumn copy) {
+ public ProjectedColumn copyTo(ProjectedColumn copy) {
copy.name = this.name;
copy.type = this.type;
copy.symbol = (ElementSymbol)this.symbol.clone();
+ return copy;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -70,7 +70,7 @@
public TextColumn clone() {
TextColumn clone = new TextColumn();
clone.width = this.width;
- this.copy(clone);
+ this.copyTo(clone);
return clone;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -90,7 +90,7 @@
@Override
public XMLColumn clone() {
XMLColumn clone = new XMLColumn();
- super.copy(clone);
+ super.copyTo(clone);
clone.ordinal = this.ordinal;
clone.path = this.path;
if (this.defaultExpression != null) {
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-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -26,6 +26,7 @@
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.BatchedUpdateCommand;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.CompareCriteria;
@@ -658,6 +659,14 @@
postVisitVisitor(obj);
}
+ @Override
+ public void visit(ArrayTable obj) {
+ preVisitVisitor(obj);
+ visitNode(obj.getArrayValue());
+ visitNode(obj.getGroupSymbol());
+ postVisitVisitor(obj);
+ }
+
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
doVisit(object, visitor, order, false);
}
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-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -38,6 +38,7 @@
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.AtomicCriteria;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.CacheHint;
@@ -83,6 +84,7 @@
import org.teiid.query.sql.lang.Update;
import org.teiid.query.sql.lang.WithQueryCommand;
import org.teiid.query.sql.lang.XMLTable;
+import org.teiid.query.sql.lang.TableFunctionReference.ProjectedColumn;
import org.teiid.query.sql.lang.TextTable.TextColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.proc.AssignmentStatement;
@@ -1905,7 +1907,32 @@
addTabs(0);
visitNode(obj.getBlock());
}
+
+ @Override
+ public void visit(ArrayTable obj) {
+ append("ARRAYTABLE("); //$NON-NLS-1$
+ visitNode(obj.getArrayValue());
+ append(SPACE);
+ append(NonReserved.COLUMNS);
+ for (Iterator<ProjectedColumn> cols = obj.getColumns().iterator(); cols.hasNext();) {
+ ProjectedColumn col = cols.next();
+ append(SPACE);
+ outputDisplayName(col.getName());
+ append(SPACE);
+ append(col.getType());
+ if (cols.hasNext()) {
+ append(","); //$NON-NLS-1$
+ }
+ }
+
+ append(")");//$NON-NLS-1$
+ append(SPACE);
+ append(AS);
+ append(SPACE);
+ outputDisplayName(obj.getName());
+ }
+
public static String escapeSinglePart( String part ) {
if (isReservedWord(part)) {
return ID_ESCAPE_CHAR + part + ID_ESCAPE_CHAR;
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-02-10 19:56:37 UTC (rev 2903)
@@ -1092,7 +1092,7 @@
GroupSymbol group = null;
int updateCount = 0;
Token updateToken = null;
- List elements = null;
+ List<TableFunctionReference.ProjectedColumn> elements = null;
SetClauseList using = null;
DynamicCommand dcStmt = new DynamicCommand();
SetClauseList setClauseList = null;
@@ -1114,7 +1114,11 @@
]
{
dcStmt.setIntoGroup(group);
- dcStmt.setAsColumns(elements);
+ List<ElementSymbol> symbols = new ArrayList(elements.size());
+ for (TableFunctionReference.ProjectedColumn col : elements) {
+ symbols.add(col.getSymbol());
+ }
+ dcStmt.setAsColumns(symbols);
dcStmt.setAsClauseSet(true);
}
]
@@ -1174,27 +1178,25 @@
* Create elements with datatypes
* @throws ParseException if parsing failed
*/
-List createElementsWithTypes(ParseInfo info) :
+List<TableFunctionReference.ProjectedColumn> createElementsWithTypes(ParseInfo info) :
{
String element = null;
- Constant type = null;
- List elements = new ArrayList();
+ String type = null;
+ List<TableFunctionReference.ProjectedColumn> elements = new ArrayList<TableFunctionReference.ProjectedColumn>();
}
{
element = id()
- type = dataType()
+ type = dataTypeString()
{
- ElementSymbol symbol = new ElementSymbol(validateElementName(element));
- symbol.setType(DataTypeManager.getDataTypeClass(type.getValue().toString()));
+ TableFunctionReference.ProjectedColumn symbol = new TableFunctionReference.ProjectedColumn(validateElementName(element), type);
elements.add(symbol);
}
(LOOKAHEAD(2) <COMMA>
element = id()
- type = dataType()
+ type = dataTypeString()
{
- symbol = new ElementSymbol(validateElementName(element));
- symbol.setType(DataTypeManager.getDataTypeClass(type.getValue().toString()));
- elements.add(symbol);
+ symbol = new TableFunctionReference.ProjectedColumn(validateElementName(element), type);
+ elements.add(symbol);
}
)*
{
@@ -2087,6 +2089,8 @@
{
( LOOKAHEAD(<ID> <LPAREN>, { "texttable".equalsIgnoreCase(getToken(1).image) }) clause = textTable(info)
|
+ LOOKAHEAD(<ID> <LPAREN>, { "arraytable".equalsIgnoreCase(getToken(1).image) }) clause = arrayTable(info)
+ |
clause = xmlTable(info)
|
clause = unaryFromClause(info)
@@ -2150,6 +2154,27 @@
}
}
+ArrayTable arrayTable(ParseInfo info) :
+{
+ Expression array = null;
+ List<TableFunctionReference.ProjectedColumn> columns;
+ String aliasID = null;
+}
+{
+ <ID> <LPAREN> array = expression(info)
+ nonReserved("COLUMNS")
+ columns = createElementsWithTypes(info)
+ <RPAREN>
+ [<AS>] aliasID=id()
+ {
+ ArrayTable result = new ArrayTable();
+ result.setArrayValue(array);
+ result.setColumns(columns);
+ result.setName(validateAlias(aliasID));
+ return result;
+ }
+}
+
TextTable textTable(ParseInfo info) :
{
Expression file = null;
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-10 19:56:37 UTC (rev 2903)
@@ -269,6 +269,12 @@
SQLParser.Invalid_short_name=Invalid simple identifier format: [{0}]
SQLParser.Invalid_char={0} value must be a single character: [{1}].
SQLParser.expected_non_reserved=Expected non-reserved word {0}, but was {1}.
+SystemSource.array_length_desc=Get the length of the given array value
+SystemSource.array_param1=Array
+SystemSource.array_length_result=The array length
+SystemSource.array_get_desc=Get the object value at the given array index
+SystemSource.array_get_param2=Array index
+SystemSource.array_get_result=The object value
SystemSource.Add_desc=Converts escape sequences in the given string to their actual characters.
SystemSource.unescape_param1=String to be unescaped
SystemSource.unescape_result=Unescaped string
@@ -786,9 +792,9 @@
FileStoreageManager.not_a_directory={0} is not a valid storage manager directory.
FileStoreageManager.space_exhausted=Max buffer space of {0} bytes has been exceed. The current operation will be aborted.
-TextTableNode.no_value=No value found for column \"{0}\" in the row ending on text line {1} in {2}.
-TextTableNode.conversion_error=Could not convert value for column \"{0}\" in the row ending on text line {1} in {2}.
-TextTableNode.header_missing=HEADER entry missing for column name \"{0}\" in {1}.
+TextTableNode.no_value=No value found for column {0} in the row ending on text line {1} in {2}.
+TextTableNode.conversion_error=Could not convert value for column {0} in the row ending on text line {1} in {2}.
+TextTableNode.header_missing=HEADER entry missing for column name {0} in {1}.
TextTableNode.unclosed=Text parse error: Unclosed qualifier at end of text in {0}.
TextTableNode.character_not_allowed=Text parse error: Non-whitespace character found between the qualifier and the delimiter in text line {0} in {1}.
TextTableNode.unknown_escape=Text parse error: Unknown escape sequence \\{0} in text line {1} in {2}.
@@ -895,4 +901,8 @@
Translate.error=Cannot translate criteria "{0}", it is not matched by selector "{1}"
-MultiSource.out_procedure=The multisource plan must execute a procedure returning parameter values exactly 1: {0}
\ No newline at end of file
+MultiSource.out_procedure=The multisource plan must execute a procedure returning parameter values exactly 1: {0}
+
+FunctionMethods.not_array_value=Expected a java.sql.Array, or java array type, but got: {0}
+FunctionMethods.array_index=Array index out of range: {0}
+ArrayTableNode.conversion_error=Could not convert value for column: {0}
\ No newline at end of file
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -33,7 +33,6 @@
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Iterator;
import java.util.Properties;
import java.util.TimeZone;
@@ -90,9 +89,9 @@
// ################################## TEST HELPERS ################################
- private FunctionDescriptor helpCreateDescriptor(String name, Class[] types) {
+ private FunctionDescriptor helpCreateDescriptor(String name, Class<?>[] types) {
final String fname = name;
- final Class[] ftypes = types;
+ final Class<?>[] ftypes = types;
return new FunctionDescriptor() {
public String getName() {
return fname;
@@ -100,10 +99,10 @@
public PushDown getPushdown() {
return PushDown.CAN_PUSHDOWN;
}
- public Class[] getTypes() {
+ public Class<?>[] getTypes() {
return ftypes;
}
- public Class getReturnType() {
+ public Class<?> getReturnType() {
return null;
}
@@ -132,19 +131,19 @@
};
}
- private void helpFindFunction(String fname, Class[] types, FunctionDescriptor expected) {
+ private void helpFindFunction(String fname, Class<?>[] types, FunctionDescriptor expected) {
FunctionDescriptor actual = library.findFunction(fname, types);
assertEquals("Function names do not match: ", expected.getName().toLowerCase(), actual.getName().toLowerCase()); //$NON-NLS-1$
assertEquals("Arg lengths do not match: ", expected.getTypes().length, actual.getTypes().length); //$NON-NLS-1$
}
- private void helpFindFunctionFail(String fname, Class[] types) {
+ private void helpFindFunctionFail(String fname, Class<?>[] types) {
FunctionDescriptor actual = library.findFunction(fname, types);
assertNull("Function was found but should not have been: " + actual, actual); //$NON-NLS-1$
}
- private void helpFindConversions(String fname, Class[] types, FunctionDescriptor[] expected) {
+ private void helpFindConversions(String fname, Class<?>[] types, FunctionDescriptor[] expected) {
FunctionDescriptor[] actual = library.determineNecessaryConversions(fname, null, types, false);
@@ -190,17 +189,17 @@
}
}
- private void helpInvokeMethod(String fname, Class[] types, Object[] inputs, CommandContext context, Object expectedOutput) throws FunctionExecutionException {
+ private void helpInvokeMethod(String fname, Class<?>[] types, Object[] inputs, CommandContext context, Object expectedOutput) throws FunctionExecutionException {
Object actualOutput = helpInvokeMethod(fname, types, inputs, context);
assertEquals("Actual function output not equal to expected: ", expectedOutput, actualOutput); //$NON-NLS-1$
}
- private Object helpInvokeMethod(String fname, Class[] types,
+ private Object helpInvokeMethod(String fname, Class<?>[] types,
Object[] inputs, CommandContext context)
throws FunctionExecutionException {
if (types == null) {
// Build type signature
- types = new Class[inputs.length];
+ types = new Class<?>[inputs.length];
for(int i=0; i<inputs.length; i++) {
types[i] = DataTypeManager.determineDataTypeClass(inputs[i]);
}
@@ -241,167 +240,167 @@
// ################################## ACTUAL TESTS ################################
@Test public void testFindFunction1() {
- helpFindFunction("convert", new Class[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }) );
+ helpFindFunction("convert", new Class<?>[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }) );
}
@Test public void testFindFunction2() {
- helpFindFunction("cast", new Class[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor(FunctionLibrary.CAST, new Class[] { T_INTEGER, T_STRING }) );
+ helpFindFunction("cast", new Class<?>[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor(FunctionLibrary.CAST, new Class<?>[] { T_INTEGER, T_STRING }) );
}
@Test public void testFindFunction3() {
- helpFindFunction("curdate", new Class[0], //$NON-NLS-1$
- helpCreateDescriptor("curdate", new Class[0])); //$NON-NLS-1$
+ helpFindFunction("curdate", new Class<?>[0], //$NON-NLS-1$
+ helpCreateDescriptor("curdate", new Class<?>[0])); //$NON-NLS-1$
}
@Test public void testFindFunction4() {
- helpFindFunctionFail("curdate", new Class[] { T_INTEGER }); //$NON-NLS-1$
+ helpFindFunctionFail("curdate", new Class<?>[] { T_INTEGER }); //$NON-NLS-1$
}
@Test public void testFindFunction5() {
- helpFindFunction("+", new Class[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("+", new Class[] { T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("+", new Class<?>[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("+", new Class<?>[] { T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction6() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER, T_FLOAT}); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER, T_FLOAT}); //$NON-NLS-1$
}
@Test public void testFindFunction7() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER, T_FLOAT, T_INTEGER}); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER, T_FLOAT, T_INTEGER}); //$NON-NLS-1$
}
@Test public void testFindFunction8() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER}); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER}); //$NON-NLS-1$
}
@Test public void testFindFunction9() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER, T_NULL }); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER, T_NULL }); //$NON-NLS-1$
}
@Test public void testFindFunction10() {
- helpFindFunction("substring", new Class[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("substring", new Class[] { T_STRING, T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("substring", new Class<?>[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("substring", new Class<?>[] { T_STRING, T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction11() {
- helpFindFunction("substring", new Class[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("substring", new Class[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("substring", new Class<?>[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("substring", new Class<?>[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction12() {
- helpFindFunction("context", new Class[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("context", new Class[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("context", new Class<?>[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("context", new Class<?>[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction12a() {
- helpFindFunction("rowlimit", new Class[] { T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("rowlimit", new Class[] { T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("rowlimit", new Class<?>[] { T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("rowlimit", new Class<?>[] { T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction12b() {
- helpFindFunction("rowlimitexception", new Class[] { T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("rowlimitexception", new Class[] { T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("rowlimitexception", new Class<?>[] { T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("rowlimitexception", new Class<?>[] { T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFind0ArgConversion1() {
helpFindConversions(
- "curdate", new Class[] {}, //$NON-NLS-1$
+ "curdate", new Class<?>[] {}, //$NON-NLS-1$
new FunctionDescriptor[0] );
}
@Test public void testFind0ArgConversion2() {
helpFindConversions(
- "curdate", new Class[] { T_INTEGER }, //$NON-NLS-1$
+ "curdate", new Class<?>[] { T_INTEGER }, //$NON-NLS-1$
null );
}
@Test public void testFind1ArgConversion1() {
helpFindConversions(
- "length", new Class[] { T_STRING }, //$NON-NLS-1$
+ "length", new Class<?>[] { T_STRING }, //$NON-NLS-1$
new FunctionDescriptor[1] );
}
@Test public void testFind1ArgConversion2() {
helpFindConversions(
- "length", new Class[] { T_INTEGER }, //$NON-NLS-1$
+ "length", new Class<?>[] { T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING })
} );
}
@Test public void testFind1ArgConversion3() {
helpFindConversions(
- "length", new Class[] { DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
+ "length", new Class<?>[] { DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.TIMESTAMP, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.TIMESTAMP, T_STRING })
} );
}
@Test public void testFind2ArgConversion1() {
helpFindConversions(
- "+", new Class[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[2] );
}
@Test public void testFind2ArgConversion2() {
helpFindConversions(
- "+", new Class[] { T_INTEGER, T_FLOAT }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_INTEGER, T_FLOAT }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_FLOAT, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_FLOAT, T_STRING }) } );
}
@Test public void testFind2ArgConversion3() {
helpFindConversions(
- "+", new Class[] { T_FLOAT, T_INTEGER }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_FLOAT, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_FLOAT, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_FLOAT, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }) } );
}
@Test public void testFind2ArgConversion4() {
helpFindConversions(
- "+", new Class[] { T_STRING, T_FLOAT }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_STRING, T_FLOAT }, //$NON-NLS-1$
null );
}
@Test public void testFind2ArgConversion5() {
helpFindConversions(
- "+", new Class[] { T_NULL, T_NULL }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_NULL, T_NULL }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }) } );
}
@Test public void testFind2ArgConversion6() {
helpFindConversions(
- "+", new Class[] { T_NULL, T_INTEGER }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_NULL, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
null } );
}
@Test public void testFind2ArgConversion7() {
helpFindConversions(
- "+", new Class[] { T_INTEGER, T_NULL }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_INTEGER, T_NULL }, //$NON-NLS-1$
new FunctionDescriptor[] {
null,
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }) } );
}
@Test public void testFind3ArgConversion1() {
helpFindConversions(
- "substring", new Class[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[3] );
}
@Test public void testFind3ArgConversion2() {
helpFindConversions(
- "substring", new Class[] { T_INTEGER, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_INTEGER, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }),
null,
null
} );
@@ -409,45 +408,45 @@
@Test public void testFind3ArgConversion3() {
helpFindConversions(
- "substring", new Class[] { T_INTEGER, T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_INTEGER, T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }),
null,
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
} );
}
@Test public void testFind3ArgConversion4() {
helpFindConversions(
- "substring", new Class[] { T_STRING, T_INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_STRING, T_INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
null );
}
@Test public void testFind3ArgConversion5() {
helpFindConversions(
- "substring", new Class[] { T_STRING, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_STRING, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
new FunctionDescriptor[] {
null,
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
} );
}
@Test public void testFind3ArgConversion6() {
helpFindConversions(
- "substring", new Class[] { T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
} );
}
@Test public void testFind3ArgConversion7() {
helpFindConversions(
- "substring", new Class[] { T_NULL, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_NULL, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
null,
null }
);
@@ -455,36 +454,32 @@
@Test public void testFind3ArgConversion8() {
helpFindConversions(
- "substring", new Class[] { T_NULL, T_NULL, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_NULL, T_NULL, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
null }
);
}
@Test public void testFind3ArgConversion9() {
helpFindConversions(
- "substring", new Class[] { T_NULL, T_NULL, T_NULL }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_NULL, T_NULL, T_NULL }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }) }
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }) }
);
}
// Walk through all functions by metadata
@Test public void testEnumerateForms() {
- Collection categories = library.getFunctionCategories();
- Iterator catIter = categories.iterator();
- while(catIter.hasNext()) {
- String category = (String) catIter.next();
+ Collection<String> categories = library.getFunctionCategories();
+ for (String category : categories) {
//System.out.println("Category: " + category);
- Collection functions = library.getFunctionForms(category);
- Iterator functionIter = functions.iterator();
- while(functionIter.hasNext()) {
- FunctionForm form = (FunctionForm) functionIter.next();
+ Collection<FunctionForm> functions = library.getFunctionForms(category);
+ for (FunctionForm form : functions) {
//System.out.println("\tFunction: " + form.getDisplayString());
// Lookup this form
@@ -739,38 +734,38 @@
}
@Test public void testFindFunction13() {
- helpFindFunction("formatTime", new Class[] { T_TIME, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatTime", new Class[] { T_TIME, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("formatTime", new Class<?>[] { T_TIME, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatTime", new Class<?>[] { T_TIME, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction14() {
- helpFindFunction("formatDate", new Class[] { T_DATE, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatDate", new Class[] { T_DATE, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("formatDate", new Class<?>[] { T_DATE, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatDate", new Class<?>[] { T_DATE, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction15() {
- helpFindFunction("formatTimestamp", new Class[] { T_TIMESTAMP, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatTimestamp", new Class[] { T_TIMESTAMP, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("formatTimestamp", new Class<?>[] { T_TIMESTAMP, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatTimestamp", new Class<?>[] { T_TIMESTAMP, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction16() {
- helpFindFunction("parseTime", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseTime", new Class[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("parseTime", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseTime", new Class<?>[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction17() {
- helpFindFunction("parseDate", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseDate", new Class[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("parseDate", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseDate", new Class<?>[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction18() {
- helpFindFunction("parseTimestamp", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseTimestamp", new Class[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("parseTimestamp", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseTimestamp", new Class<?>[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction19() {
- helpFindFunction("env", new Class[] {T_STRING}, //$NON-NLS-1$
- helpCreateDescriptor("env", new Class[] {T_STRING})); //$NON-NLS-1$
+ helpFindFunction("env", new Class<?>[] {T_STRING}, //$NON-NLS-1$
+ helpCreateDescriptor("env", new Class<?>[] {T_STRING})); //$NON-NLS-1$
}
@Test public void testInvokeFormatTimestamp1() {
@@ -798,62 +793,62 @@
}
@Test public void testFindFormatInteger() {
- helpFindFunction("formatInteger", new Class[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatInteger", new Class[] { T_INTEGER, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatInteger", new Class<?>[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatInteger", new Class<?>[] { T_INTEGER, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatFloat() {
- helpFindFunction("formatFloat", new Class[] { T_FLOAT, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatFloat", new Class[] { T_FLOAT, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatFloat", new Class<?>[] { T_FLOAT, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatFloat", new Class<?>[] { T_FLOAT, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatDouble() {
- helpFindFunction("formatDouble", new Class[] { T_DOUBLE, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatDouble", new Class[] { T_DOUBLE, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatDouble", new Class<?>[] { T_DOUBLE, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatDouble", new Class<?>[] { T_DOUBLE, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatLong() {
- helpFindFunction("formatLong", new Class[] { T_LONG, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatLong", new Class[] { T_LONG, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatLong", new Class<?>[] { T_LONG, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatLong", new Class<?>[] { T_LONG, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatBigInteger() {
- helpFindFunction("formatBigInteger", new Class[] { T_BIG_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatBigInteger", new Class[] { T_BIG_INTEGER, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatBigInteger", new Class<?>[] { T_BIG_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatBigInteger", new Class<?>[] { T_BIG_INTEGER, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatBigDecimal() {
- helpFindFunction("formatBigDecimal", new Class[] { T_BIG_DECIMAL, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatBigDecimal", new Class[] { T_BIG_DECIMAL, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatBigDecimal", new Class<?>[] { T_BIG_DECIMAL, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatBigDecimal", new Class<?>[] { T_BIG_DECIMAL, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseInteger() {
- helpFindFunction("parseInteger", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseInteger", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseInteger", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseInteger", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseLong() {
- helpFindFunction("parseLong", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseLong", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseLong", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseLong", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseDouble() {
- helpFindFunction("parseDouble", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseDouble", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseDouble", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseDouble", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseFloat() {
- helpFindFunction("parseFloat", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseFloat", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseFloat", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseFloat", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseBigInteger() {
- helpFindFunction("parseBigInteger", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseBigInteger", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseBigInteger", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseBigInteger", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseBigDecimal() {
- helpFindFunction("parseBigDecimal", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseBigDecimal", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseBigDecimal", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseBigDecimal", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testInvokeParseInteger() {
@@ -1195,13 +1190,13 @@
@Test public void testInvokeRand() throws Exception {
helpInvokeMethod("rand", new Object[] {new Integer(100)}, new Double(0.7220096548596434)); //$NON-NLS-1$
// this does not actually fail but returns a result
- assertNotNull(helpInvokeMethod("rand", new Class[] {Integer.class}, new Object[] {null}, null)); //$NON-NLS-1$
+ assertNotNull(helpInvokeMethod("rand", new Class<?>[] {Integer.class}, new Object[] {null}, null)); //$NON-NLS-1$
}
@Test public void testInvokeUser() throws Exception {
CommandContext c = new CommandContext();
c.setUserName("foodude"); //$NON-NLS-1$
- helpInvokeMethod("user", new Class[] {}, new Object[] {}, c, "foodude"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpInvokeMethod("user", new Class<?>[] {}, new Object[] {}, c, "foodude"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testInvokeEnv() throws Exception {
@@ -1209,26 +1204,26 @@
Properties props = new Properties();
props.setProperty("env_test", "env_value"); //$NON-NLS-1$ //$NON-NLS-2$
c.setEnvironmentProperties(props);
- helpInvokeMethod("env", new Class[] {String.class}, new Object[] {"env_test"}, c, "env_value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- helpInvokeMethod("env", new Class[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
+ helpInvokeMethod("env", new Class<?>[] {String.class}, new Object[] {"env_test"}, c, "env_value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpInvokeMethod("env", new Class<?>[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
}
@Test public void testInvokeCommandPayload() throws Exception {
CommandContext c = new CommandContext();
c.setCommandPayload("payload_too heavy"); //$NON-NLS-1$
- helpInvokeMethod("commandpayload", new Class[] {}, new Object[] {}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$
- helpInvokeMethod("commandpayload", new Class[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
+ helpInvokeMethod("commandpayload", new Class<?>[] {}, new Object[] {}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpInvokeMethod("commandpayload", new Class<?>[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
Properties props = new Properties();
props.setProperty("payload", "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$
c.setCommandPayload(props);
- helpInvokeMethod("commandpayload", new Class[] {String.class}, new Object[] {"payload"}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpInvokeMethod("commandpayload", new Class<?>[] {String.class}, new Object[] {"payload"}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@Test public void testNullDependent() {
- FunctionDescriptor actual = library.findFunction("concat2", new Class[] {String.class, String.class}); //$NON-NLS-1$
+ FunctionDescriptor actual = library.findFunction("concat2", new Class<?>[] {String.class, String.class}); //$NON-NLS-1$
assertTrue(actual.isNullDependent());
- actual = library.findFunction("concat", new Class[] {String.class, String.class}); //$NON-NLS-1$
+ actual = library.findFunction("concat", new Class<?>[] {String.class, String.class}); //$NON-NLS-1$
assertFalse(actual.isNullDependent());
}
@@ -1331,17 +1326,17 @@
}
@Test public void testInvokeNull() throws Exception {
- helpInvokeMethod(SourceSystemFunctions.LTRIM, new Class[] {DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null }, null, null);
+ helpInvokeMethod(SourceSystemFunctions.LTRIM, new Class<?>[] {DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null }, null, null);
}
@Test public void testInvokeNull1() throws Exception {
- helpInvokeMethod(SourceSystemFunctions.CONCAT, new Class[] {DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null, String.valueOf(1) }, null, null);
+ helpInvokeMethod(SourceSystemFunctions.CONCAT, new Class<?>[] {DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null, String.valueOf(1) }, null, null);
}
@Test public void testInvokeXslTransform() throws Exception {
CommandContext c = new CommandContext();
c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
- ClobType result = (ClobType)helpInvokeMethod("xsltransform", new Class[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
+ ClobType result = (ClobType)helpInvokeMethod("xsltransform", new Class<?>[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
new Object[] {DataTypeManager.transformValue("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Catalogs xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Catalog><Items><Item ItemID=\"001\"><Name>Lamp</Name><Quantity>5</Quantity></Item></Items></Catalog></Catalogs>", DataTypeManager.DefaultDataClasses.XML),
DataTypeManager.transformValue("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"@*|node()\"><xsl:copy><xsl:apply-templates select=\"@*|node()\"/></xsl:copy></xsl:template><xsl:template match=\"Quantity\"/></xsl:stylesheet>", DataTypeManager.DefaultDataClasses.XML)}, c);
@@ -1352,7 +1347,7 @@
@Test public void testInvokeXmlConcat() throws Exception {
CommandContext c = new CommandContext();
c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
- XMLType result = (XMLType)helpInvokeMethod("xmlconcat", new Class[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
+ XMLType result = (XMLType)helpInvokeMethod("xmlconcat", new Class<?>[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
new Object[] {DataTypeManager.transformValue("<bar/>", DataTypeManager.DefaultDataClasses.XML), DataTypeManager.transformValue("<Catalogs xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Catalog><Items><Item ItemID=\"001\"><Name>Lamp</Name><Quantity>5</Quantity></Item></Items></Catalog></Catalogs>", DataTypeManager.DefaultDataClasses.XML)}, c);
String xml = ObjectConverterUtil.convertToString(result.getCharacterStream());
@@ -1362,7 +1357,7 @@
@Test public void testInvokeXmlComment() throws Exception {
CommandContext c = new CommandContext();
c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
- XMLType result = (XMLType)helpInvokeMethod("xmlcomment", new Class[] {DataTypeManager.DefaultDataClasses.STRING},
+ XMLType result = (XMLType)helpInvokeMethod("xmlcomment", new Class<?>[] {DataTypeManager.DefaultDataClasses.STRING},
new Object[] {"comment"}, c);
String xml = ObjectConverterUtil.convertToString(result.getCharacterStream());
@@ -1370,43 +1365,47 @@
}
@Test public void testToChars() throws Exception {
- Clob result = (Clob)helpInvokeMethod("to_chars", new Class[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "ASCII" }, null); //$NON-NLS-1$
+ Clob result = (Clob)helpInvokeMethod("to_chars", new Class<?>[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "ASCII" }, null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("hello world", string);
}
@Test public void testToBytes() throws Exception {
- Blob result = (Blob)helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("hello world".toCharArray())), "UTF32" }, null); //$NON-NLS-1$
+ Blob result = (Blob)helpInvokeMethod("to_bytes", new Class<?>[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("hello world".toCharArray())), "UTF32" }, null); //$NON-NLS-1$
assertEquals(44, result.length()); //4 bytes / char
}
@Test public void testToChars1() throws Exception {
- Clob result = (Clob)helpInvokeMethod("to_chars", new Class[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "BASE64" }, null); //$NON-NLS-1$
+ Clob result = (Clob)helpInvokeMethod("to_chars", new Class<?>[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "BASE64" }, null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("hello world", new String(Base64.decode(string), "ASCII"));
}
@Test public void testToChars2() throws Exception {
- Clob result = (Clob)helpInvokeMethod("to_chars", new Class[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "HEX" }, null); //$NON-NLS-1$
+ Clob result = (Clob)helpInvokeMethod("to_chars", new Class<?>[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "HEX" }, null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("68656C6C6F20776F726C64", string);
}
@Test public void testToBytes2() throws Exception {
- Blob result = (Blob)helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("68656C6C6F20776F726C64".toCharArray())), "HEX" }, null); //$NON-NLS-1$
+ Blob result = (Blob)helpInvokeMethod("to_bytes", new Class<?>[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("68656C6C6F20776F726C64".toCharArray())), "HEX" }, null); //$NON-NLS-1$
assertEquals("hello world", new String(ObjectConverterUtil.convertToCharArray(result.getBinaryStream(), -1, "ASCII")));
}
@Test(expected=FunctionExecutionException.class) public void testToBytes3() throws Exception {
- helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("a".toCharArray())), "BASE64" }, null); //$NON-NLS-1$
+ helpInvokeMethod("to_bytes", new Class<?>[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("a".toCharArray())), "BASE64" }, null); //$NON-NLS-1$
}
- @Test() public void testunescape() throws Exception {
- assertEquals("\r\t", helpInvokeMethod("unescape", new Class[] {DefaultDataClasses.STRING}, new Object[] { "\r\\\t" }, null)); //$NON-NLS-1$
+ @Test() public void testUnescape() throws Exception {
+ assertEquals("\r\t", helpInvokeMethod("unescape", new Class<?>[] {DefaultDataClasses.STRING}, new Object[] { "\r\\\t" }, null)); //$NON-NLS-1$
}
@Test() public void testUuid() throws Exception {
- assertNotNull(helpInvokeMethod("uuid", new Class[] {}, new Object[] {}, null)); //$NON-NLS-1$
+ assertNotNull(helpInvokeMethod("uuid", new Class<?>[] {}, new Object[] {}, null)); //$NON-NLS-1$
}
+ @Test() public void testArrayGet() throws Exception {
+ assertEquals(1, helpInvokeMethod("array_get", new Class<?>[] {DefaultDataClasses.OBJECT, DefaultDataClasses.INTEGER}, new Object[] {new Object[] {1}, 1}, null)); //$NON-NLS-1$
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -43,6 +43,7 @@
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.language.SQLConstants.Reserved;
import org.teiid.language.SortSpecification.NullOrdering;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.CompareCriteria;
@@ -78,6 +79,7 @@
import org.teiid.query.sql.lang.SubqueryCompareCriteria;
import org.teiid.query.sql.lang.SubqueryFromClause;
import org.teiid.query.sql.lang.SubquerySetCriteria;
+import org.teiid.query.sql.lang.TableFunctionReference;
import org.teiid.query.sql.lang.TextTable;
import org.teiid.query.sql.lang.UnaryFromClause;
import org.teiid.query.sql.lang.Update;
@@ -6857,5 +6859,20 @@
query.setFrom(from);
helpTest("TABLE X", "SELECT * FROM X", query);
}
+
+ @Test public void testArrayTable() throws Exception {
+ String sql = "SELECT * from arraytable(null columns x string, y date) as x"; //$NON-NLS-1$
+ Query query = new Query();
+ query.setSelect(new Select(Arrays.asList(new AllSymbol())));
+ ArrayTable tt = new ArrayTable();
+ tt.setArrayValue(new Constant(null, DataTypeManager.DefaultDataClasses.OBJECT));
+ List<TableFunctionReference.ProjectedColumn> columns = new ArrayList<TableFunctionReference.ProjectedColumn>();
+ columns.add(new TableFunctionReference.ProjectedColumn("x", "string"));
+ columns.add(new TableFunctionReference.ProjectedColumn("y", "date"));
+ tt.setColumns(columns);
+ tt.setName("x");
+ query.setFrom(new From(Arrays.asList(tt)));
+ helpTest(sql, "SELECT * FROM ARRAYTABLE(null COLUMNS x string, y date) AS x", query);
+ }
}
Added: trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -0,0 +1,83 @@
+/*
+ * 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.processor;
+
+import static org.teiid.query.processor.TestProcessor.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+@SuppressWarnings({"unchecked", "nls"})
+public class TestArrayTable {
+
+ @Test public void testCorrelatedTextTable() throws Exception {
+ String sql = "select x.* from bqt1.smalla, arraytable(objectvalue COLUMNS x string, y integer) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList("a", 1),
+ Arrays.asList("b", 3),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testCorrelatedTextTable1() throws Exception {
+ String sql = "select z from bqt1.smalla, arraytable(objectvalue COLUMNS x string, y integer, z long) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList(Long.valueOf(2)),
+ Arrays.asList(Long.valueOf(6)),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test(expected=TeiidProcessingException.class) public void testCorrelatedTextTable2() throws Exception {
+ String sql = "select y from bqt1.smalla, arraytable(objectvalue COLUMNS y integer) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {};
+
+ process(sql, expected);
+ }
+
+ @Test(expected=TeiidProcessingException.class) public void testCorrelatedTextTable3() throws Exception {
+ String sql = "select x.* from bqt1.smalla, arraytable(objectvalue COLUMNS x string, y integer, z integer, aa object) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {};
+
+ process(sql, expected);
+ }
+
+ public static void process(String sql, List[] expectedResults) throws Exception {
+ HardcodedDataManager dataManager = new HardcodedDataManager();
+ dataManager.addData("SELECT bqt1.smalla.objectvalue FROM bqt1.smalla", new List[] {Collections.singletonList(new Object[] {"a", 1, 2}), Collections.singletonList(new Object[] {"b", 3, 6})} );
+ ProcessorPlan plan = helpGetPlan(helpParse(sql), RealMetadataFactory.exampleBQTCached());
+ helpProcess(plan, createCommandContext(), dataManager, expectedResults);
+ }
+
+}
Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
===================================================================
--- trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -146,6 +146,9 @@
registerFunction("uuid", new StandardSQLFunction("uuid", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
registerFunction("unescape", new StandardSQLFunction("unescape", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ registerFunction("array_get", new StandardSQLFunction("uuid", Hibernate.OBJECT)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("array_length", new StandardSQLFunction("unescape", Hibernate.INTEGER)); //$NON-NLS-1$ //$NON-NLS-2$
}
public boolean dropConstraints() {
14 years, 10 months
teiid SVN: r2902 - trunk/common-core/src/main/java/org/teiid/core/types.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-08 11:08:30 -0500 (Tue, 08 Feb 2011)
New Revision: 2902
Modified:
trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
Log:
TEIIDDES-836 longvarchar should be imported as clob
Modified: trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-08 16:00:47 UTC (rev 2901)
+++ trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-08 16:08:30 UTC (rev 2902)
@@ -89,7 +89,7 @@
private static Map<String, String> CLASSNAME_TO_NAME = new HashMap<String, String>();
static {
- addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.CHAR);
+ addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.CHAR, Types.NVARCHAR, Types.NCHAR);
addTypeMapping(CHAR, CHAR_CLASS, Types.CHAR, false);
addTypeMapping(BOOLEAN, BOOLEAN_CLASS, Types.BIT, Types.BOOLEAN);
addTypeMapping(TIME, TIME_CLASS, Types.TIME);
@@ -104,16 +104,12 @@
addTypeMapping(SHORT, SHORT_CLASS, Types.SMALLINT);
addTypeMapping(LONG, LONG_CLASS, Types.BIGINT);
addTypeMapping(OBJECT, OBJECT_CLASS, Types.JAVA_OBJECT);
- addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB, Types.LONGVARCHAR);
+ addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB, Types.LONGVARCHAR, Types.LONGNVARCHAR, Types.NCLOB);
addTypeMapping(BLOB, BLOB_CLASS, Types.BLOB, Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY);
addTypeMapping(NULL, null, Types.NULL);
addTypeMapping(XML, XML_CLASS, Types.SQLXML);
- TYPE_TO_NAME_MAP.put(Types.NVARCHAR, STRING);
- TYPE_TO_NAME_MAP.put(Types.LONGNVARCHAR, STRING);
- TYPE_TO_NAME_MAP.put(Types.NCHAR, CHAR);
- TYPE_TO_NAME_MAP.put(Types.NCLOB, CLOB);
}
private static void addTypeMapping(String typeName, String javaClass, int sqlType, int ... secondaryTypes) {
14 years, 10 months
teiid SVN: r2901 - trunk/common-core/src/main/java/org/teiid/core/types.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-08 11:00:47 -0500 (Tue, 08 Feb 2011)
New Revision: 2901
Modified:
trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
Log:
TEIIDDES-836 longvarchar should be imported as clob
Modified: trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-07 19:38:21 UTC (rev 2900)
+++ trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-08 16:00:47 UTC (rev 2901)
@@ -89,7 +89,7 @@
private static Map<String, String> CLASSNAME_TO_NAME = new HashMap<String, String>();
static {
- addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.LONGVARCHAR, Types.CHAR);
+ addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.CHAR);
addTypeMapping(CHAR, CHAR_CLASS, Types.CHAR, false);
addTypeMapping(BOOLEAN, BOOLEAN_CLASS, Types.BIT, Types.BOOLEAN);
addTypeMapping(TIME, TIME_CLASS, Types.TIME);
@@ -104,7 +104,7 @@
addTypeMapping(SHORT, SHORT_CLASS, Types.SMALLINT);
addTypeMapping(LONG, LONG_CLASS, Types.BIGINT);
addTypeMapping(OBJECT, OBJECT_CLASS, Types.JAVA_OBJECT);
- addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB);
+ addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB, Types.LONGVARCHAR);
addTypeMapping(BLOB, BLOB_CLASS, Types.BLOB, Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY);
addTypeMapping(NULL, null, Types.NULL);
14 years, 10 months
teiid SVN: r2900 - tags.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-07 14:38:21 -0500 (Mon, 07 Feb 2011)
New Revision: 2900
Added:
tags/teiid-parent-7.1.1.GA/
Log:
adding 7.1.1.GA tag
Copied: tags/teiid-parent-7.1.1.GA (from rev 2899, branches/7.1.x)
14 years, 10 months
teiid SVN: r2899 - in branches/7.1.x: adminshell and 35 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-07 14:35:34 -0500 (Mon, 07 Feb 2011)
New Revision: 2899
Modified:
branches/7.1.x/adminshell/pom.xml
branches/7.1.x/api/pom.xml
branches/7.1.x/build/pom.xml
branches/7.1.x/cache-jbosscache/pom.xml
branches/7.1.x/client/pom.xml
branches/7.1.x/common-core/pom.xml
branches/7.1.x/connectors/connector-file/pom.xml
branches/7.1.x/connectors/connector-ldap/pom.xml
branches/7.1.x/connectors/connector-salesforce/pom.xml
branches/7.1.x/connectors/connector-ws/pom.xml
branches/7.1.x/connectors/pom.xml
branches/7.1.x/connectors/salesforce-api/pom.xml
branches/7.1.x/connectors/sandbox/pom.xml
branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml
branches/7.1.x/connectors/translator-file/pom.xml
branches/7.1.x/connectors/translator-jdbc/pom.xml
branches/7.1.x/connectors/translator-ldap/pom.xml
branches/7.1.x/connectors/translator-loopback/pom.xml
branches/7.1.x/connectors/translator-salesforce/pom.xml
branches/7.1.x/connectors/translator-ws/pom.xml
branches/7.1.x/console/pom.xml
branches/7.1.x/documentation/admin-guide/pom.xml
branches/7.1.x/documentation/caching-guide/pom.xml
branches/7.1.x/documentation/client-developers-guide/pom.xml
branches/7.1.x/documentation/developer-guide/pom.xml
branches/7.1.x/documentation/pom.xml
branches/7.1.x/documentation/quick-start-example/pom.xml
branches/7.1.x/documentation/reference/pom.xml
branches/7.1.x/engine/pom.xml
branches/7.1.x/hibernate-dialect/pom.xml
branches/7.1.x/jboss-integration/pom.xml
branches/7.1.x/metadata/pom.xml
branches/7.1.x/pom.xml
branches/7.1.x/runtime/pom.xml
branches/7.1.x/test-integration/common/pom.xml
branches/7.1.x/test-integration/db/pom.xml
branches/7.1.x/test-integration/pom.xml
Log:
updating to GA version
Modified: branches/7.1.x/adminshell/pom.xml
===================================================================
--- branches/7.1.x/adminshell/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/adminshell/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-adminshell</artifactId>
Modified: branches/7.1.x/api/pom.xml
===================================================================
--- branches/7.1.x/api/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/api/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-api</artifactId>
Modified: branches/7.1.x/build/pom.xml
===================================================================
--- branches/7.1.x/build/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/build/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid</artifactId>
Modified: branches/7.1.x/cache-jbosscache/pom.xml
===================================================================
--- branches/7.1.x/cache-jbosscache/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/cache-jbosscache/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-cache-jbosscache</artifactId>
Modified: branches/7.1.x/client/pom.xml
===================================================================
--- branches/7.1.x/client/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/client/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-client</artifactId>
Modified: branches/7.1.x/common-core/pom.xml
===================================================================
--- branches/7.1.x/common-core/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/common-core/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-common-core</artifactId>
Modified: branches/7.1.x/connectors/connector-file/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-file/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-file/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-file</artifactId>
Modified: branches/7.1.x/connectors/connector-ldap/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-ldap/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-ldap/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-ldap</artifactId>
Modified: branches/7.1.x/connectors/connector-salesforce/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-salesforce/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-salesforce/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-salesforce</artifactId>
Modified: branches/7.1.x/connectors/connector-ws/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-ws/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-ws/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-ws</artifactId>
Modified: branches/7.1.x/connectors/pom.xml
===================================================================
--- branches/7.1.x/connectors/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
Modified: branches/7.1.x/connectors/salesforce-api/pom.xml
===================================================================
--- branches/7.1.x/connectors/salesforce-api/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/salesforce-api/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>salesforce-api</artifactId>
Modified: branches/7.1.x/connectors/sandbox/pom.xml
===================================================================
--- branches/7.1.x/connectors/sandbox/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/sandbox/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid.connectors</groupId>
Modified: branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml
===================================================================
--- branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>sandbox</artifactId>
<groupId>org.jboss.teiid.connectors</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-yahoo</artifactId>
Modified: branches/7.1.x/connectors/translator-file/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-file/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-file/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-file</artifactId>
Modified: branches/7.1.x/connectors/translator-jdbc/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-jdbc/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-jdbc/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-jdbc</artifactId>
Modified: branches/7.1.x/connectors/translator-ldap/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-ldap/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-ldap/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-ldap</artifactId>
Modified: branches/7.1.x/connectors/translator-loopback/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-loopback/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-loopback/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-loopback</artifactId>
Modified: branches/7.1.x/connectors/translator-salesforce/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-salesforce/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-salesforce/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-salesforce</artifactId>
Modified: branches/7.1.x/connectors/translator-ws/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-ws/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-ws/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-ws</artifactId>
Modified: branches/7.1.x/console/pom.xml
===================================================================
--- branches/7.1.x/console/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/console/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -4,7 +4,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: branches/7.1.x/documentation/admin-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/admin-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/admin-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>admin-guide</artifactId>
Modified: branches/7.1.x/documentation/caching-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/caching-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/caching-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>caching-guide</artifactId>
Modified: branches/7.1.x/documentation/client-developers-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/client-developers-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/client-developers-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>client-developers-guide</artifactId>
Modified: branches/7.1.x/documentation/developer-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/developer-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/developer-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>developer-guide</artifactId>
Modified: branches/7.1.x/documentation/pom.xml
===================================================================
--- branches/7.1.x/documentation/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version> </parent>
+ <version>7.1.1.GA</version> </parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
Modified: branches/7.1.x/documentation/quick-start-example/pom.xml
===================================================================
--- branches/7.1.x/documentation/quick-start-example/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/quick-start-example/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>quick-start-example</artifactId>
Modified: branches/7.1.x/documentation/reference/pom.xml
===================================================================
--- branches/7.1.x/documentation/reference/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/reference/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>reference</artifactId>
Modified: branches/7.1.x/engine/pom.xml
===================================================================
--- branches/7.1.x/engine/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/engine/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-engine</artifactId>
Modified: branches/7.1.x/hibernate-dialect/pom.xml
===================================================================
--- branches/7.1.x/hibernate-dialect/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/hibernate-dialect/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-hibernate-dialect</artifactId>
Modified: branches/7.1.x/jboss-integration/pom.xml
===================================================================
--- branches/7.1.x/jboss-integration/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/jboss-integration/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
Modified: branches/7.1.x/metadata/pom.xml
===================================================================
--- branches/7.1.x/metadata/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/metadata/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-metadata</artifactId>
Modified: branches/7.1.x/pom.xml
===================================================================
--- branches/7.1.x/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -5,7 +5,7 @@
<artifactId>teiid-parent</artifactId>
<packaging>pom</packaging>
<name>Teiid</name>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
<description>Federated SQL and XML query engine.</description>
<properties>
<ant.version>1.7.0</ant.version>
Modified: branches/7.1.x/runtime/pom.xml
===================================================================
--- branches/7.1.x/runtime/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/runtime/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
Modified: branches/7.1.x/test-integration/common/pom.xml
===================================================================
--- branches/7.1.x/test-integration/common/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/test-integration/common/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-test-integration</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-integration-common</artifactId>
Modified: branches/7.1.x/test-integration/db/pom.xml
===================================================================
--- branches/7.1.x/test-integration/db/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/test-integration/db/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -9,7 +9,7 @@
<parent>
<artifactId>teiid-test-integration</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: branches/7.1.x/test-integration/pom.xml
===================================================================
--- branches/7.1.x/test-integration/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/test-integration/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-test-integration</artifactId>
14 years, 10 months
teiid SVN: r2898 - in trunk: build/kits/jboss-container and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-07 13:50:57 -0500 (Mon, 07 Feb 2011)
New Revision: 2898
Modified:
trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
Log:
TEIID-1464 adding support for a uuid function
Modified: trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -145,5 +145,7 @@
public static final String XMLPI = "xmlpi"; //$NON-NLS-1$
public static final String JSONTOXML = "jsontoxml"; //$NON-NLS-1$
+
+ public static final String UUID = "uuid"; //$NON-NLS-1$
}
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-07 18:50:57 UTC (rev 2898)
@@ -29,6 +29,7 @@
<LI><B>Virtual procedure out params</B> - virtual procedures can now have RETURN/OUT/INOUT parameters to return values.
<LI><B>OLAP</B> - OLAP translator is now part of Teiid kit using OLAP4J
<LI><B>Multi-source procedures</B> - multi-source handling was expanded to cover stored procedure execution. See the Reference for more.
+ <LI><B>UUID function</B> - was added to generate type 4 UUIDs and the Hibernate dialect was updated to support the GUIDGenerator.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-07 18:50:57 UTC (rev 2898)
@@ -2074,6 +2074,17 @@
<para>The two argument form is provided for backwards compatibility. roleType is a string and must be 'data'</para>
</section>
</section>
+ <section>
+ <title>Miscellaneous Functions</title>
+ <para>Other functions.</para>
+ <section>
+ <title>uuid</title>
+ <para>Retuns a universally unique identifier.</para>
+ <para><synopsis>uuid()</synopsis></para>
+ <para>the return type is string.</para>
+ <para>Generates a type 4 (pseudo randomly generated) UUID using a cryptographically strong random number generator. The format is XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX where each X is a hex digit.</para>
+ </section>
+ </section>
<section id="nondeterministic_functions">
<title>Nondeterministic Function Handling</title>
<para>Teiid categorizes functions by varying degrees of determinism.
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -41,6 +41,7 @@
import java.util.Date;
import java.util.Properties;
import java.util.TimeZone;
+import java.util.UUID;
import org.teiid.api.exception.query.ExpressionEvaluationException;
import org.teiid.api.exception.query.FunctionExecutionException;
@@ -1375,4 +1376,8 @@
return i;
}
+ public static String uuid() {
+ return UUID.randomUUID().toString();
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -193,6 +193,7 @@
}
addUnescape();
+ addUuidFunction();
}
private void addUnescape() {
@@ -284,6 +285,14 @@
rand.setDeterminism(Determinism.NONDETERMINISTIC);
functions.add(rand);
}
+
+ private void addUuidFunction() {
+ FunctionMethod rand = new FunctionMethod(SourceSystemFunctions.UUID, QueryPlugin.Util.getString("SystemSource.uuid_desc"), MISCELLANEOUS, FUNCTION_CLASS, "uuid", //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter[] {},
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.uuid_result_desc")) ); //$NON-NLS-1$ //$NON-NLS-2$
+ rand.setDeterminism(Determinism.NONDETERMINISTIC);
+ functions.add(rand);
+ }
private void addDoubleFunction(String name, String description) {
functions.add(
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-07 18:50:57 UTC (rev 2898)
@@ -386,6 +386,8 @@
SystemSource.Rand_desc=Random Number
SystemSource.Rand_arg=Number
SystemSource.Rand_result_desc=Generated Random Number
+SystemSource.uuid_desc=UUID
+SystemSource.uuid_result_desc=type 4 UUID
SystemSource.Double_arg2=Number
SystemSource.Atan_arg1=Number parameter1
SystemSource.Atan_arg2=Number parameter2
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -1405,4 +1405,8 @@
assertEquals("\r\t", helpInvokeMethod("unescape", new Class[] {DefaultDataClasses.STRING}, new Object[] { "\r\\\t" }, null)); //$NON-NLS-1$
}
+ @Test() public void testUuid() throws Exception {
+ assertNotNull(helpInvokeMethod("uuid", new Class[] {}, new Object[] {}, null)); //$NON-NLS-1$
+ }
+
}
Modified: trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
===================================================================
--- trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -138,6 +138,14 @@
registerFunction("modifytimezone", new StandardSQLFunction("modifytimezone", Hibernate.TIMESTAMP)); //$NON-NLS-1$ //$NON-NLS-2$
registerFunction("convert", new StandardSQLFunction("convert")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ registerFunction("to_bytes", new StandardSQLFunction("to_bytes", Hibernate.BLOB)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("to_chars", new StandardSQLFunction("to_chars", Hibernate.CLOB)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("from_unittime", new StandardSQLFunction("from_unittime", Hibernate.TIMESTAMP)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("session_id", new StandardSQLFunction("session_id", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ registerFunction("uuid", new StandardSQLFunction("uuid", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("unescape", new StandardSQLFunction("unescape", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
}
public boolean dropConstraints() {
@@ -243,6 +251,11 @@
public String getForUpdateString(String aliases) {
return ""; //$NON-NLS-1$
}
+
+ @Override
+ public String getSelectGUIDString() {
+ return "select uuid()"; //$NON-NLS-1$
+ }
}
14 years, 10 months
teiid SVN: r2897 - in trunk: api/src/main/java/org/teiid/metadata and 30 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-03 17:15:05 -0500 (Thu, 03 Feb 2011)
New Revision: 2897
Removed:
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
Modified:
trunk/api/src/main/java/org/teiid/language/Function.java
trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
trunk/api/src/main/java/org/teiid/metadata/Schema.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
Log:
TEIID-231 various refinements to function handling.
Modified: trunk/api/src/main/java/org/teiid/language/Function.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/Function.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/language/Function.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -26,16 +26,18 @@
import java.util.List;
import org.teiid.language.visitor.LanguageObjectVisitor;
+import org.teiid.metadata.FunctionMethod;
/**
* Represents a function. A function has a name and 0..n
* Expressions that are parameters.
*/
-public class Function extends BaseLanguageObject implements Expression {
+public class Function extends BaseLanguageObject implements Expression, MetadataReference<FunctionMethod> {
private String name;
private List<Expression> parameters;
private Class<?> type;
+ private FunctionMethod metadataObject;
public Function(String name, List<? extends Expression> params, Class<?> type) {
this.name = name;
@@ -47,6 +49,15 @@
this.type = type;
}
+ @Override
+ public FunctionMethod getMetadataObject() {
+ return metadataObject;
+ }
+
+ public void setMetadataObject(FunctionMethod metadataObject) {
+ this.metadataObject = metadataObject;
+ }
+
/**
* Get name of the function
* @return Function name
Modified: trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,6 +29,7 @@
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
+import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
@@ -109,7 +110,8 @@
@XmlElement(name="inputParameters")
protected List<FunctionParameter> inParameters = new ArrayList<FunctionParameter>();
private FunctionParameter outputParameter;
-
+ private Schema parent;
+
protected FunctionMethod() {
}
@@ -371,7 +373,7 @@
List<FunctionParameter> otherInputs = other.getInputParameters();
for(int i=0; i<thisInputs.size(); i++) {
- boolean paramMatch = compareWithNull(thisInputs.get(i), otherInputs.get(i));
+ boolean paramMatch = EquivalenceUtil.areEqual(thisInputs.get(i), otherInputs.get(i));
if(! paramMatch) {
return false;
}
@@ -385,26 +387,6 @@
}
/**
- * Compare two objects that may or may not be null and consider null==null
- * as true.
- * @param o1 Object 1
- * @param o2 Object 2
- * @return True if o1 and o2 are null or if they both aren't and they are equal
- */
- private boolean compareWithNull(Object o1, Object o2) {
- if(o1 == null) {
- if(o2 == null) {
- return true;
- }
- return false;
- }
- if(o2 == null) {
- return false;
- }
- return o1.equals(o2);
- }
-
- /**
* Return string version for debugging purposes
* @return String representation of function method
*/
@@ -473,5 +455,13 @@
}
return false;
}
-
+
+ public void setParent(Schema parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public Schema getParent() {
+ return parent;
+ }
}
Modified: trunk/api/src/main/java/org/teiid/metadata/Schema.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/Schema.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/Schema.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -52,7 +52,10 @@
}
public void addFunction(FunctionMethod function) {
- this.functions.put(function.getName().toLowerCase(), function);
+ function.setParent(this);
+ if (this.functions.put(function.getName().toLowerCase(), function) != null) {
+ throw new AssertionError("Duplicate function " + function.getName()); //$NON-NLS-1$
+ }
}
/**
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -650,7 +650,7 @@
}
public List<FunctionMethod> getPushDownFunctions(){
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
/**
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,8 @@
<h4>from 7.3</h4>
<ul>
<li>The use of an IN procedure parameter with the name "source_name" in a multi-source model, will now be treated the parameter that controls which source
- the procedure will execute against.
+ the procedure will execute against.
+ <li>Dynamic VDB functions injected via ExecutionFactory.getPushdownFunctions are now scoped to the SYS schema and have a fully qualified name that includes their source type. For example, instead of oracle_model.relate - which was only valid against the oracle_model source, there is now the SYS.oracle_sdo.relate function that is valid for all Oracle sources. Any fully-qualified reference to these functions will need updated.
</ul>
<h4>from 7.2</h4>
@@ -189,9 +190,8 @@
<h2><a name="Licenses">Licenses</a></h2>
<p>Teiid is licensed under the <a href="LICENSE-lgpl-2.1.txt">LGPL</a>. The
-license texts for Teiid and the thirdparty components it uses may be found in the teiid-docs/licenses
-directory of the distribution. <a href="teiid-docs/licenses">Browse
-Licenses</a>
+license texts for Teiid and the thirdparty components it uses may be found in the <a href="teiid-docs/licenses">teiid-docs/licenses</a>
+directory of the distribution.
</p>
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,31 +116,31 @@
@Override
public List<FunctionMethod> getPushDownFunctions(){
List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
- pushdownFunctions.add(new FunctionMethod(JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_ISSAMENODE, JCR_ISSAMENODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISSAMENODE, JCR_ISSAMENODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_CONTAINS, JCR_CONTAINS, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_CONTAINS, JCR_CONTAINS, JCR,
new FunctionParameter[] {
new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("searchExpr", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_REFERENCE, JCR_REFERENCE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_REFERENCE, JCR_REFERENCE, JCR,
new FunctionParameter[] {
new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -38,42 +38,42 @@
public static final String FILTER = "sdo_filter"; //$NON-NLS-1$
public static final String WITHIN_DISTANCE = "sdo_within_distance"; //$NON-NLS-1$
public static final String NEAREST_NEIGHBOR_DISTANCE = "sdo_nn_distance"; //$NON-NLS-1$
- private static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
+ public static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
public static List<FunctionMethod> getOracleSpatialFunctions(){
List<FunctionMethod> spatialFuncs = new ArrayList<FunctionMethod>();
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -81,7 +81,7 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -89,7 +89,7 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -97,47 +97,47 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -91,7 +91,7 @@
public void testPredicate() throws Exception {
String input = "SELECT x.jcr_primaryType from nt_base inner join nt_base as x on jcr_issamenode(nt_base.jcr_path, x.jcr_path) = true where jcr_isdescendantnode(nt_base.jcr_path, 'x/y/z') = true and jcr_reference(nt_base.mode_properties) = 'x'"; //$NON-NLS-1$
- String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON issamenode(g_0, g_1) WHERE isdescendantnode(g_0, 'x/y/z') AND reference(g_0.*) = 'x'"; //$NON-NLS-1$
+ String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON ISSAMENODE(g_0, g_1) WHERE ISDESCENDANTNODE(g_0, 'x/y/z') AND REFERENCE(g_0.*) = 'x'"; //$NON-NLS-1$
helpTestVisitor(input, output);
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-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -128,7 +128,7 @@
@Test
public void testDateFunctions() throws Exception {
String input = "select dayName(timestampValue), dayOfWeek(timestampValue), quarter(timestampValue) from bqt1.smalla"; //$NON-NLS-1$
- String output = "SELECT {fn dayName(SmallA.TimestampValue)}, {fn dayOfWeek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
+ String output = "SELECT {fn dayname(SmallA.TimestampValue)}, {fn dayofweek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
helpTestVisitor(getBQTVDB(),
input,
Modified: trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
===================================================================
--- trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,13 +142,13 @@
@Override
public List<FunctionMethod> getPushDownFunctions(){
List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
- pushdownFunctions.add(new FunctionMethod(INCLUDES, INCLUDES, SALESFORCE,
+ pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' +INCLUDES, INCLUDES, SALESFORCE,
new FunctionParameter[] {
new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(EXCLUDES, EXCLUDES, SALESFORCE,
+ pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' + EXCLUDES, EXCLUDES, SALESFORCE,
new FunctionParameter[] {
new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
===================================================================
--- trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml 2011-02-03 22:15:05 UTC (rev 2897)
@@ -8,7 +8,7 @@
creating a UDF.</para>
<section id="define_udf">
<title>UDF Definition</title>
- <para>The FunctionDefinition.xmi file provides metadata to the
+ <para>A FunctionDefinition.xmi file provides metadata to the
query engine on User Defined Functions. See the Designer Documentation for more on creating a Function Definition Model.</para>
<itemizedlist>
<para>The following are used to define a UDF.</para>
@@ -19,24 +19,20 @@
mind:
<itemizedlist>
<listitem>
- <para>You cannot use a reserved word, which includes
- existing Teiid System function names. You cannot
- overload existing Teiid System functions.</para>
+ <para>You cannot overload existing Teiid System functions.</para>
</listitem>
<listitem>
<para>The function name must be unique among user-defined
- functions for the number of arguments. You can use the
+ functions in its model for the number of arguments. You can use the
same function name for different numbers of types of
arguments. Hence, you can overload your user-defined
functions.</para>
</listitem>
<listitem>
- <para>The function name can only contain letters,
- numbers, and the underscore (_). Your function name must
- start with a letter.</para>
+ <para>The function name cannot contain the '.' character.</para>
</listitem>
<listitem>
- <para>The function name cannot exceed 128 characters.
+ <para>The function name cannot exceed 255 characters.
</para>
</listitem>
</itemizedlist>
@@ -225,4 +221,18 @@
created in in the Designer Tool, it can be added to the VDB for use
by Teiid.</para>
</section>
+ <section>
+ <title>User Defined Functions in Dynamic VDBs</title>
+ <para>Dynamic VDBs do not use Designer generated artifacts, such as a FunctionDefinition.xmi file.
+ Even with that limitation dynamic vdbs may still utilize UDFs through custom coding.
+ The <code>ExecutionFactory.getMetadata</code> call allows for the definition of metadata via a <code>MetadataFactory.</code>
+ Use the <code>MetadataFactory.addFunction</code> to add function for use only by that translator instance.
+ Functions added directly to the source schema are specific to that schema - their fully qualified name will include the schema and the function can not be pushed to a different source.
+ </para>
+ <para>The <code>ExecutionFactory.getPushdownFunctions</code> method can be used to describe functions that are valid against all instances of a given translator type. The function names are expected to be
+ prefixed by the translator type, or some other logical grouping, e.g. salesforce.includes. The full name of the function once imported into the system will qualified by the SYS schema, e.g. SYS.salesforce.includes.
+ </para>
+ <para>Any funcitons added via these mechanisms do not need to be declared in <code>ExecutionFactory.getSupportedFunctions.</code> Any of the additional handling, such as adding a <code>FunctionModifier</code>, covered above is also applicable here. All pushdown functions will have function name set to only the simple name. Schema or other qualification will be removed.
+ Handling, such as function modifiers, can check the function metadata if there is the potential for an ambiguity.</para>
+ </section>
</chapter>
\ No newline at end of file
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-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -495,12 +495,22 @@
org.teiid.language.Function translate(Function function) {
Expression [] args = function.getArgs();
List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>(args.length);
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- params.add(translate(args[i]));
- }
+ for (int i = 0; i < args.length; i++) {
+ params.add(translate(args[i]));
}
- return new org.teiid.language.Function(function.getName(), params, function.getType());
+ String name = function.getName();
+ if (function.getFunctionDescriptor() != null) {
+ name = function.getFunctionDescriptor().getName();
+ }
+ name = SingleElementSymbol.getShortName(name);
+
+ //if there is any ambiguity in the function name it will be up to the translator logic to check the
+ //metadata
+ org.teiid.language.Function result = new org.teiid.language.Function(name, params, function.getType());
+ if (function.getFunctionDescriptor() != null) {
+ result.setMetadataObject(function.getFunctionDescriptor().getMethod());
+ }
+ return result;
}
SearchedCase translate(SearchedCaseExpression expr) {
@@ -515,7 +525,7 @@
org.teiid.language.Expression translate(ScalarSubquery ss) {
- return new org.teiid.language.ScalarSubquery(translate((QueryCommand)ss.getCommand()));
+ return new org.teiid.language.ScalarSubquery(translate(ss.getCommand()));
}
org.teiid.language.Expression translate(SingleElementSymbol symbol) {
@@ -562,11 +572,12 @@
/* Insert */
org.teiid.language.Insert translate(Insert insert) {
- List elements = insert.getVariables();
+ List<ElementSymbol> elements = insert.getVariables();
List<ColumnReference> translatedElements = new ArrayList<ColumnReference>();
- for (Iterator i = elements.iterator(); i.hasNext();) {
- translatedElements.add(translate((ElementSymbol)i.next()));
- }
+
+ for (ElementSymbol elementSymbol : elements) {
+ translatedElements.add(translate(elementSymbol));
+ }
InsertValueSource valueSource = null;
if (insert.getQueryExpression() != null) {
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-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -694,7 +694,7 @@
this.processWorkerPool = new ThreadReuseExecutor(DQPConfiguration.PROCESS_PLAN_QUEUE_NAME, config.getMaxThreads());
if (cacheFactory.isReplicated()) {
- matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.LRU, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
+ matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.EXPIRATION, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
matTables.setBufferManager(this.bufferManager);
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -31,33 +31,27 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.TransformationException;
-import org.teiid.core.util.Assertion;
-import org.teiid.core.util.HashCodeUtil;
import org.teiid.core.util.PropertiesUtils;
-import org.teiid.metadata.FunctionMethod.PushDown;
+import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.FunctionMethod.Determinism;
+import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.QueryPlugin;
import org.teiid.query.util.CommandContext;
/**
* The FunctionDescriptor describes a particular function instance enough
- * that the function library can retrieve a function instance based on the
- * descriptor.
+ * to invoke the function.
*/
public class FunctionDescriptor implements Serializable, Cloneable {
private static final long serialVersionUID = 5374103983118037242L;
private static final boolean ALLOW_NAN_INFINITY = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.allowNanInfinity", false); //$NON-NLS-1$
- private String name;
- private PushDown pushdown = PushDown.CAN_PUSHDOWN;
- private Class[] types;
- private Class returnType;
- private int hash;
+ private Class<?>[] types;
+ private Class<?> returnType;
private boolean requiresContext;
- private boolean nullDependent;
- private Determinism deterministic = Determinism.DETERMINISTIC;
+ private FunctionMethod method;
// This is transient as it would be useless to invoke this method in
// a different VM. This function descriptor can be used to look up
@@ -67,52 +61,29 @@
FunctionDescriptor() {
}
- /**
- * Construct a function descriptor with all the info
- * @param name Name of function
- * @param types Types of the arguments
- * @param returnType Type of the return
- * @param invocationMethod Reflection method used to invoke the function
- * @param requiresContext during execution requires command context to be pushed into method as first argument
- */
- FunctionDescriptor(String name, PushDown pushdown, Class[] types, Class returnType, Method invocationMethod, boolean requiresContext, boolean nullDependent, Determinism deterministic) {
- Assertion.isNotNull(name);
- Assertion.isNotNull(types);
- Assertion.isNotNull(returnType);
-
- this.name = name;
- this.pushdown = pushdown;
+ FunctionDescriptor(FunctionMethod method, Class<?>[] types,
+ Class<?> outputType, Method invocationMethod,
+ boolean requiresContext) {
this.types = types;
- this.returnType = returnType;
+ this.returnType = outputType;
this.invocationMethod = invocationMethod;
this.requiresContext = requiresContext;
- this.nullDependent = nullDependent;
- this.deterministic = deterministic;
-
- // Compute hash code
- hash = HashCodeUtil.hashCode(0, name);
- for(int i=0; i<types.length; i++) {
- hash = HashCodeUtil.hashCode(hash, types[i]);
- }
+ this.method = method;
}
public String getName() {
- return this.name;
+ return this.method.getName();
}
public PushDown getPushdown() {
- return this.pushdown;
+ return this.method.getPushdown();
}
- void setPushdown(PushDown pushdown) {
- this.pushdown = pushdown;
- }
-
- public Class[] getTypes() {
+ public Class<?>[] getTypes() {
return this.types;
}
- public Class getReturnType() {
+ public Class<?> getReturnType() {
return this.returnType;
}
@@ -124,51 +95,8 @@
return this.requiresContext;
}
- public int hashCode() {
- return this.hash;
- }
-
- public boolean equals(Object obj) {
- if(obj == this) {
- return true;
- }
-
- if(obj == null || !(obj instanceof FunctionDescriptor)) {
- return false;
- }
- FunctionDescriptor other = (FunctionDescriptor) obj;
-
- // Compare names
- if(! this.getName().equals(other.getName())) {
- return false;
- }
-
- // Compare arg types
- Class[] thisTypes = this.getTypes();
- Class[] otherTypes = other.getTypes();
- if(thisTypes.length != otherTypes.length) {
- return false;
- }
- for(int i=0; i<thisTypes.length; i++) {
- if(! thisTypes[i].equals(otherTypes[i])) {
- return false;
- }
- }
-
- if (this.nullDependent != other.isNullDependent()) {
- return false;
- }
-
- if (this.deterministic != other.deterministic) {
- return false;
- }
-
- // Must be a match
- return true;
- }
-
public String toString() {
- StringBuffer str = new StringBuffer(this.name);
+ StringBuffer str = new StringBuffer(this.method.getName());
str.append("("); //$NON-NLS-1$
for(int i=0; i<types.length; i++) {
if(types[i] != null) {
@@ -190,17 +118,13 @@
}
public boolean isNullDependent() {
- return nullDependent;
+ return !this.method.isNullOnNull();
}
public Determinism getDeterministic() {
- return deterministic;
+ return this.method.getDeterminism();
}
- void setDeterministic(Determinism deterministic) {
- this.deterministic = deterministic;
- }
-
public Object clone() {
try {
return super.clone();
@@ -208,12 +132,15 @@
throw new TeiidRuntimeException(e);
}
}
+
+ public FunctionMethod getMethod() {
+ return method;
+ }
- void setReturnType(Class returnType) {
+ void setReturnType(Class<?> returnType) {
this.returnType = returnType;
}
-
/**
* Invoke the function described in the function descriptor, using the
* values provided. Return the result of the function.
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,7 @@
* information and instead differentiates function signatures based on their
* function name and the names of the arguments.
*/
-public class FunctionForm implements Serializable, Comparable {
+public class FunctionForm implements Serializable, Comparable<FunctionForm> {
private static final long serialVersionUID = 2411783099304320334L;
private String name;
@@ -245,42 +245,32 @@
* @param obj Other object
* @return 1 if other > this, 0 if other == this, -1 if other < this
*/
- public int compareTo(Object obj) {
- if(obj == this) {
- return 0;
- } else if(obj == null) {
- // Should never happen, but sort nulls low
- return -1;
- } else {
- // may throw ClassCastException - this is expected for compareTo()
- FunctionForm other = (FunctionForm) obj;
+ public int compareTo(FunctionForm other) {
+ int compare = this.getName().compareTo( other.getName() );
+ if(compare != 0) {
+ return compare;
+ }
- int compare = this.getName().compareTo( other.getName() );
+ // Look further into arg names to compare as names are ==
+ List otherArgs = other.getArgNames();
+ List myArgs = this.getArgNames();
+
+ // Compare # of args first
+ if(myArgs.size() < otherArgs.size()) {
+ return -1;
+ } else if(myArgs.size() > otherArgs.size()) {
+ return 1;
+ } // else continue
+
+ // Same # of args
+ for(int i=0; i < myArgs.size(); i++) {
+ compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
if(compare != 0) {
return compare;
}
-
- // Look further into arg names to compare as names are ==
- List otherArgs = other.getArgNames();
- List myArgs = this.getArgNames();
-
- // Compare # of args first
- if(myArgs.size() < otherArgs.size()) {
- return -1;
- } else if(myArgs.size() > otherArgs.size()) {
- return 1;
- } // else continue
-
- // Same # of args
- for(int i=0; i < myArgs.size(); i++) {
- compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
- if(compare != 0) {
- return compare;
- }
- }
-
- // Same
- return 0;
}
+
+ // Same
+ return 0;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,9 +25,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.TreeSet;
import org.teiid.api.exception.query.InvalidFunctionException;
import org.teiid.api.exception.query.QueryResolverException;
@@ -108,9 +108,9 @@
* Get all function categories, sorted in alphabetical order
* @return List of function category names, sorted in alphabetical order
*/
- public List getFunctionCategories() {
+ public List<String> getFunctionCategories() {
// Remove category duplicates
- HashSet categories = new HashSet();
+ TreeSet<String> categories = new TreeSet<String>();
categories.addAll( systemFunctions.getCategories() );
if (this.userFunctions != null) {
for (FunctionTree tree: this.userFunctions) {
@@ -118,9 +118,7 @@
}
}
- // Sort alphabetically
- ArrayList categoryList = new ArrayList(categories);
- Collections.sort(categoryList);
+ ArrayList<String> categoryList = new ArrayList<String>(categories);
return categoryList;
}
@@ -129,8 +127,8 @@
* @param category Category name
* @return List of {@link FunctionForm}s in a category
*/
- public List getFunctionForms(String category) {
- List forms = new ArrayList();
+ public List<FunctionForm> getFunctionForms(String category) {
+ List<FunctionForm> forms = new ArrayList<FunctionForm>();
forms.addAll(systemFunctions.getFunctionForms(category));
if (this.userFunctions != null) {
for (FunctionTree tree: this.userFunctions) {
@@ -170,7 +168,7 @@
* @param types Array of classes representing the types
* @return Descriptor if found, null if not found
*/
- public FunctionDescriptor findFunction(String name, Class[] types) {
+ public FunctionDescriptor findFunction(String name, Class<?>[] types) {
// First look in system functions
FunctionDescriptor descriptor = systemFunctions.getFunction(name, types);
@@ -323,7 +321,7 @@
* @param targetType The target type class
* @return A CONVERT function descriptor or null if not possible
*/
- public FunctionDescriptor findTypedConversionFunction(Class sourceType, Class targetType) {
+ public FunctionDescriptor findTypedConversionFunction(Class<?> sourceType, Class<?> targetType) {
FunctionDescriptor fd = findFunction(CONVERT, new Class[] {sourceType, DataTypeManager.DefaultDataClasses.STRING});
if (fd != null) {
return copyFunctionChangeReturnType(fd, targetType);
@@ -337,7 +335,7 @@
* @param returnType The return type to apply to the copied FunctionDescriptor.
* @return The copy of FunctionDescriptor.
*/
- public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class returnType) {
+ public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class<?> returnType) {
if(fd != null) {
FunctionDescriptor fdImpl = fd;
FunctionDescriptor copy = (FunctionDescriptor)fdImpl.clone();
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,15 +29,14 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.Assertion;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
@@ -75,55 +74,32 @@
*/
private Map treeRoot = new HashMap();
private boolean validateClass;
-
+
/**
* Construct a new tree with the given source of function metadata.
* @param source The metadata source
*/
- public FunctionTree(FunctionMetadataSource source) {
- this(source, false);
+ public FunctionTree(String name, FunctionMetadataSource source) {
+ this(name, source, false);
}
/**
* Construct a new tree with the given source of function metadata.
* @param source The metadata source
*/
- public FunctionTree(FunctionMetadataSource source, boolean validateClass) {
+ public FunctionTree(String name, FunctionMetadataSource source, boolean validateClass) {
// Load data structures
this.validateClass = validateClass;
- addSource(source);
- }
- /**
- * Add all functions from a metadata source to the data structures.
- * @param source The source of the functions
- */
- private void addSource(FunctionMetadataSource source) {
- if(source == null) {
- return;
+ Collection<FunctionMethod> functions = source.getFunctionMethods();
+ for (FunctionMethod method : functions) {
+ if (!containsIndistinguishableFunction(method)){
+ // Add to tree
+ addFunction(name, source, method);
+ } else if (!CoreConstants.SYSTEM_MODEL.equalsIgnoreCase(name)) {
+ LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
+ }
}
-
- Collection functions = source.getFunctionMethods();
- if(functions != null) {
- Iterator functionIter = functions.iterator();
- while(functionIter.hasNext()) {
- Object functionObj = functionIter.next();
- if(! (functionObj instanceof FunctionMethod)) {
- Assertion.failed(QueryPlugin.Util.getString("ERR.015.001.0045", functionObj.getClass().getName())); //$NON-NLS-1$
- }
- FunctionMethod method = (FunctionMethod) functionObj;
-
- if (!containsIndistinguishableFunction(method)){
- // Store method metadata for retrieval
- addMetadata(method);
-
- // Add to tree
- addFunction(source, method);
- } else {
- LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
- }
- }
- }
}
// ---------------------- FUNCTION SELECTION USE METHODS ----------------------
@@ -143,51 +119,6 @@
}
/**
- * Store the method in the function metadata.
- * @param method The function metadata for a particular method signature
- */
- private void addMetadata(FunctionMethod method) {
- String categoryKey = method.getCategory();
- if (categoryKey == null) {
- method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
- categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
- }
- categoryKey = categoryKey.toUpperCase();
- String nameKey = method.getName().toUpperCase();
-
- // Look up function map (create if necessary)
- Set<String> functions = categories.get(categoryKey);
- if (functions == null) {
- functions = new HashSet<String>();
- categories.put(categoryKey, functions);
- }
-
- int index = -1;
- while (true){
- // Look up function in function map
- functions.add(nameKey);
-
- // Add method to list by function name
- List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
- if(knownMethods == null) {
- knownMethods = new ArrayList<FunctionMethod>();
- functionsByName.put(nameKey, knownMethods);
- }
- knownMethods.add(method);
-
- // if the function is "." delimited, then add all possible forms
- index = nameKey.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
- if (index != -1) {
- nameKey = nameKey.substring(index+1);
- }
- else {
- break;
- }
- }
- allFunctions.add(method);
- }
-
- /**
* Get collection of category names.
* @return Category names
*/
@@ -258,28 +189,94 @@
* @param source The function metadata source, which knows how to obtain the invocation class
* @param method The function metadata for a particular method signature
*/
- private void addFunction(FunctionMetadataSource source, FunctionMethod method) {
+ private void addFunction(String schema, FunctionMetadataSource source, FunctionMethod method) {
+ String categoryKey = method.getCategory();
+ if (categoryKey == null) {
+ method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
+ categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
+ }
+ categoryKey = categoryKey.toUpperCase();
+
+ // Look up function map (create if necessary)
+ Set<String> functions = categories.get(categoryKey);
+ if (functions == null) {
+ functions = new HashSet<String>();
+ categories.put(categoryKey, functions);
+ }
+
// Get method name
- String methodName = method.getName();
+ String methodName = schema + AbstractMetadataRecord.NAME_DELIM_CHAR + method.getName();
// Get input types for path
List<FunctionParameter> inputParams = method.getInputParameters();
- List<Class> inputTypes = new LinkedList<Class>();
+ List<Class<?>> inputTypes = new LinkedList<Class<?>>();
if(inputParams != null) {
for(int i=0; i<inputParams.size(); i++) {
String typeName = inputParams.get(i).getType();
inputTypes.add(DataTypeManager.getDataTypeClass(typeName));
}
}
- Class[] types = inputTypes.toArray(new Class[inputTypes.size()]);
+ Class<?>[] types = inputTypes.toArray(new Class[inputTypes.size()]);
if (method.isVarArgs()) {
inputTypes.set(inputTypes.size() - 1, Array.newInstance(inputTypes.get(inputTypes.size() - 1), 0).getClass());
}
- // Get return type
+ FunctionDescriptor descriptor = createFunctionDescriptor(source, method, inputTypes, types);
+ // Store this path in the function tree
+
+ int index = -1;
+ while(true) {
+ String nameKey = methodName.toUpperCase();
+
+ // Look up function in function map
+ functions.add(nameKey);
+
+ // Add method to list by function name
+ List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
+ if(knownMethods == null) {
+ knownMethods = new ArrayList<FunctionMethod>();
+ functionsByName.put(nameKey, knownMethods);
+ }
+ knownMethods.add(method);
+
+ Map node = treeRoot;
+ Object[] path = buildPath(methodName, types);
+ for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
+ Object pathPart = path[pathIndex];
+ Map children = (Map) node.get(pathPart);
+ if(children == null) {
+ children = new HashMap();
+ node.put(pathPart, children);
+ }
+ if (method.isVarArgs() && pathIndex == path.length - 1) {
+ node.put(DESCRIPTOR_KEY, descriptor);
+ }
+ node = children;
+ }
+
+ if (method.isVarArgs()) {
+ node.put(types[types.length - 1], node);
+ }
+ // Store the leaf descriptor in the tree
+ node.put(DESCRIPTOR_KEY, descriptor);
+
+ index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
+ if (index == -1) {
+ break;
+ }
+ methodName = methodName.substring(index+1);
+ }
+
+ allFunctions.add(method);
+ }
+
+ private FunctionDescriptor createFunctionDescriptor(
+ FunctionMetadataSource source, FunctionMethod method,
+ List<Class<?>> inputTypes, Class<?>[] types) {
+ // Get return type
FunctionParameter outputParam = method.getOutputParameter();
- Class outputType = null;
+ Class<?> outputType = null;
if(outputParam != null) {
outputType = DataTypeManager.getDataTypeClass(outputParam.getType());
}
@@ -329,39 +326,8 @@
inputTypes.add(0, CommandContext.class);
}
- FunctionDescriptor descriptor = new FunctionDescriptor(method.getName(), method.getPushdown(), types, outputType, invocationMethod, requiresContext, !method.isNullOnNull(), method.getDeterminism());
- // Store this path in the function tree
-
- int index = -1;
- while(true) {
- Map node = treeRoot;
- Object[] path = buildPath(methodName, types);
- for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
- Object pathPart = path[pathIndex];
- Map children = (Map) node.get(pathPart);
- if(children == null) {
- children = new HashMap();
- node.put(pathPart, children);
- }
- if (method.isVarArgs() && pathIndex == path.length - 1) {
- node.put(DESCRIPTOR_KEY, descriptor);
- }
- node = children;
- }
-
- if (method.isVarArgs()) {
- node.put(types[types.length - 1], node);
- }
- // Store the leaf descriptor in the tree
- node.put(DESCRIPTOR_KEY, descriptor);
-
- index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
- if (index == -1) {
- break;
- }
- methodName = methodName.substring(index+1);
- }
- }
+ return new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext);
+ }
/**
* Look up a function descriptor by signature in the tree. If none is
@@ -370,7 +336,7 @@
* @param argTypes Types of each argument in the function
* @return Descriptor which can be used to invoke the function
*/
- FunctionDescriptor getFunction(String name, Class[] argTypes) {
+ FunctionDescriptor getFunction(String name, Class<?>[] argTypes) {
// Build search path
Object[] path = buildPath(name, argTypes);
@@ -399,7 +365,7 @@
* @param argTypes Types of each arguments
* @return Path in function storage tree
*/
- private Object[] buildPath(String name, Class[] argTypes) {
+ private Object[] buildPath(String name, Class<?>[] argTypes) {
Object[] path = new Object[argTypes.length + 1];
path[0] = name.toUpperCase();
System.arraycopy(argTypes, 0, path, 1, argTypes.length);
Modified: trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,8 +22,8 @@
package org.teiid.query.function;
import java.util.Collection;
-import java.util.Collections;
+import org.teiid.core.CoreConstants;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.metadata.FunctionMetadataValidator;
import org.teiid.query.function.source.SystemSource;
@@ -47,13 +47,13 @@
// Should never happen as SystemSourcTe doesn't change
System.err.println(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
}
- systemFunctionTree = new FunctionTree(systemSource, true);
+ systemFunctionTree = new FunctionTree(CoreConstants.SYSTEM_MODEL, systemSource, true);
}
return systemFunctionTree;
}
public FunctionLibrary getSystemFunctionLibrary() {
- return new FunctionLibrary(getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+ return new FunctionLibrary(getSystemFunctions());
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -36,11 +36,11 @@
this.methods = methods;
}
- public Collection getFunctionMethods() {
+ public Collection<FunctionMethod> getFunctionMethods() {
return this.methods;
}
- public Class getInvocationClass(String className) throws ClassNotFoundException {
+ public Class<?> getInvocationClass(String className) throws ClassNotFoundException {
return Class.forName(className);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -253,26 +253,9 @@
* @throws FunctionMetadataException Thrown when string uses characters not in allowed character sets
*/
private static final void validateNameCharacters(String name, String strName) throws FunctionMetadataException {
- // First check first character
- if(name.length() > 0) {
- // Check special cases
- if(name.equals("+") || name.equals("-") || name.equals("*") || name.equals("/") || name.equals("||")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- return;
- }
-
- char firstChar = name.charAt(0);
- if(! Character.isLetter(firstChar)) {
- throw new FunctionMetadataException("ERR.015.001.0056", QueryPlugin.Util.getString("ERR.015.001.0056",strName, new Character(firstChar))); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- // Then check the rest of the characters
- for(int i=1; i<name.length(); i++) {
- char ch = name.charAt(i);
- if(! (Character.isLetterOrDigit(ch) || ch == '_')) {
- throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, new Character(ch))); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
+ if (name.indexOf('.') > 0) {
+ throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, '.')); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,7 +142,7 @@
* TransformationMetadata constructor
* @param context Object containing the info needed to lookup metadta.
*/
- public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, FunctionTree... udfFunctions) {
+ public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, Collection<FunctionTree> functionTrees) {
ArgCheck.isNotNull(store);
this.vdbMetaData = vdbMetadata;
this.store = store;
@@ -151,7 +151,11 @@
} else {
this.vdbEntries = vdbEntries;
}
- this.functionLibrary = new FunctionLibrary(systemFunctions, udfFunctions);
+ if (functionTrees == null) {
+ this.functionLibrary = new FunctionLibrary(systemFunctions);
+ } else {
+ this.functionLibrary = new FunctionLibrary(systemFunctions, functionTrees.toArray(new FunctionTree[functionTrees.size()]));
+ }
}
//==================================================================================
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-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -30,6 +30,7 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.metadata.Schema;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -206,12 +207,20 @@
if (metadata.isVirtualModel(modelID)){
return false;
}
+
+ //capabilities check is only valid for non-schema scoped functions
+ //technically the other functions are scoped to SYS, but that's
+ //not formally part of their metadata yet
+ Schema schema = function.getFunctionDescriptor().getMethod().getParent();
+ if (schema == null) {
+ // Find capabilities
+ SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
- // Find capabilities
- SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
-
- if (!caps.supportsFunction(function.getName().toLowerCase())) {
- return false;
+ if (!caps.supportsFunction(function.getFunctionDescriptor().getName().toLowerCase())) {
+ return false;
+ }
+ } else if (!schema.getFullName().equalsIgnoreCase(metadata.getFullName(modelID))) {
+ return false; //not the right schema
}
//special check to ensure that special conversions are not pushed down (this can be removed after we support type based function pushdown)
Modified: trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -88,5 +88,10 @@
public Collection<R> getItems() {
return items;
}
+
+ @Override
+ public String toString() {
+ return reportType + " " + getItems(); //$NON-NLS-1$
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -2221,11 +2221,19 @@
//rewrite alias functions
String functionLowerName = function.getName().toLowerCase();
String actualName =ALIASED_FUNCTIONS.get(functionLowerName);
+ FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
+
if (actualName != null) {
function.setName(actualName);
+ Expression[] args = function.getArgs();
+ Class<?>[] types = new Class[args.length];
+ for(int i=0; i<args.length; i++) {
+ types[i] = args[i].getType();
+ }
+ FunctionDescriptor descriptor = funcLibrary.findFunction(actualName, types);
+ function.setFunctionDescriptor(descriptor);
}
- FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
Integer code = FUNCTION_MAP.get(functionLowerName);
if (code != null) {
switch (code) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -192,12 +192,16 @@
return true;
}
- if(obj == null || ! (obj instanceof Function)) {
+ if(! (obj instanceof Function)) {
return false;
}
Function other = (Function) obj;
- if(! other.getName().equalsIgnoreCase(getName())) {
+ if (this.descriptor != null && other.descriptor != null) {
+ if (!this.descriptor.getMethod().getFullName().equals(other.descriptor.getMethod().getFullName())) {
+ return false;
+ }
+ } else if(! other.getName().equalsIgnoreCase(getName())) {
return false;
}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-03 22:15:05 UTC (rev 2897)
@@ -39,7 +39,6 @@
ERR.015.001.0042 = Illegal argument for formating: {0}
ERR.015.001.0043 = Parse Exception occurs for executing: {0} {1}
ERR.015.001.0044 = Function metadata source is of invalid type: {0}
-ERR.015.001.0045 = Function method is of invalid type: {0}
ERR.015.001.0046 = The function "{0}" will not be added because a function with the same name and signature already exists.
ERR.015.001.0047 = Unexpected exception while loading "{1}.{2}" for UDF "{0}"
FunctionTree.not_void = UDF "{0}" method "{1}" must not return void.
Deleted: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -1,115 +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.function;
-
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.UnitTestUtil;
-import org.teiid.metadata.FunctionMethod.Determinism;
-import org.teiid.metadata.FunctionMethod.PushDown;
-
-
-public class TestFunctionDescriptorImpl extends TestCase {
-
- /**
- * Constructor for TestFunctionDescriptorImpl.
- * @param name
- */
- public TestFunctionDescriptorImpl(String name) {
- super(name);
- }
-
- /**
- * Find the invocation method for a function.
- * @param source The function metadata source, which knows how to obtain the invocation class
- * @param invocationClass The class to invoke for this function
- * @param invocationMethod The method to invoke for this function
- * @param numArgs Number of arguments in method
- * @throws NoSuchMethodException
- * @throws SecurityException
- */
- private Method lookupMethod(String invocationClass, String invocationMethod, int numArgs) throws SecurityException, NoSuchMethodException {
- // Build signature
- Class[] objectSignature = new Class[numArgs];
- for(int i=0; i<numArgs; i++) {
- objectSignature[i] = Integer.TYPE;
- }
-
- // Find Method
- Method method = null;
- try {
- Class methodClass = Class.forName(invocationClass);
- method = methodClass.getMethod(invocationMethod, objectSignature);
- } catch(ClassNotFoundException e) {
- // Failed to load class, so can't load method - this will fail at invocation time.
- // We don't fail here because this situation can occur in the modeler, which does
- // not have the function jar files. The modeler never invokes, so this isn't a
- // problem.
- return null;
- }
-
- return method;
- }
-
- public void test1() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN, //$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2) , false, true, Determinism.DETERMINISTIC); //$NON-NLS-1$ //$NON-NLS-2$
-
- UnitTestUtil.helpTestEquivalence(0, f1, f1);
- }
-
- public void test2() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- UnitTestUtil.helpTestEquivalence(0, f1, f2);
- }
-
- public void test3() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, false, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-
- FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- assertNotSame("objects should not be equal", f1, f2); //$NON-NLS-1$
- }
-
-}
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,12 +22,7 @@
package org.teiid.query.function;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -38,7 +33,6 @@
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
import java.util.Properties;
import java.util.TimeZone;
@@ -84,7 +78,7 @@
private static final Class<Date> T_DATE = DataTypeManager.DefaultDataClasses.DATE;
private static final Class<Timestamp> T_TIMESTAMP = DataTypeManager.DefaultDataClasses.TIMESTAMP;
- private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+ private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions());
@Before public void setUp() {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -50,7 +50,7 @@
*/
@Test public void testWalkTree() {
SystemSource source = new SystemSource(false);
- FunctionTree ft = new FunctionTree(source);
+ FunctionTree ft = new FunctionTree("foo", source);
Collection<String> categories = ft.getCategories();
for (String category : categories) {
@@ -78,11 +78,11 @@
new FunctionParameter("output", DataTypeManager.DefaultDataTypes.STRING), false, Determinism.DETERMINISTIC); //$NON-NLS-1$
//allowed, since we're not validating the class
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method))));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method))));
//should fail, no class
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -92,7 +92,7 @@
//should fail, no method
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -102,7 +102,7 @@
//should fail, not void
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -112,7 +112,7 @@
//should fail, not public
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -122,7 +122,7 @@
//should fail, not static
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -131,7 +131,7 @@
method.setInvocationMethod("y");
//valid!
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
}
@Test public void testNullCategory() {
@@ -144,7 +144,7 @@
Collection<org.teiid.metadata.FunctionMethod> list = Arrays.asList(method);
FunctionMetadataSource fms = Mockito.mock(FunctionMetadataSource.class);
Mockito.stub(fms.getFunctionMethods()).toReturn(list);
- FunctionTree ft = new FunctionTree(fms);
+ FunctionTree ft = new FunctionTree("foo", fms);
assertEquals(1, ft.getFunctionForms(FunctionCategoryConstants.MISCELLANEOUS).size());
}
Modified: trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -92,12 +92,8 @@
helpTestValidateNameFail(null);
}
- public void testValidateNameFail2() {
- helpTestValidateNameFail("123"); //$NON-NLS-1$
- }
-
public void testValidateNameFail3() {
- helpTestValidateNameFail("a b"); //$NON-NLS-1$
+ helpTestValidateNameFail("a.b"); //$NON-NLS-1$
}
public void testValidateFunction1() {
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -27,7 +27,6 @@
import java.util.List;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.metadata.Datatype;
import org.teiid.metadata.FunctionParameter;
import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.function.FunctionMetadataSource;
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,11 +22,7 @@
package org.teiid.query.optimizer;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
@@ -46,7 +42,6 @@
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -4265,7 +4260,7 @@
caps.setFunctionSupport("xyz", true); //$NON-NLS-1$
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,7 +25,10 @@
import java.util.ArrayList;
import java.util.List;
+import junit.framework.TestCase;
+
import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -33,7 +36,7 @@
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
-import org.teiid.query.optimizer.relational.rules.CapabilitiesUtil;
+import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.symbol.AggregateSymbol;
@@ -46,9 +49,7 @@
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.unittest.FakeMetadataObject;
-import junit.framework.TestCase;
-
/**
*/
public class TestCapabilitiesUtil extends TestCase {
@@ -369,7 +370,7 @@
helpTestSupportsAggregateFunction(caps, aggregate, true);
}
- public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException {
+ public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
// Set up metadata
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
FakeMetadataObject modelID = metadata.getStore().findObject("pm1", FakeMetadataObject.MODEL); //$NON-NLS-1$
@@ -377,7 +378,7 @@
// Set up capabilities
FakeCapabilitiesFinder finder = new FakeCapabilitiesFinder();
finder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
+ ResolverVisitor.resolveLanguageObject(function, metadata);
// Test capabilities util
boolean actual = CapabilitiesUtil.supportsScalarFunction(modelID, function, metadata, finder);
assertEquals("Got wrong answer for supports", expectedValue, actual); //$NON-NLS-1$
@@ -387,7 +388,7 @@
public void testSupportsScalar1() throws Exception {
BasicSourceCapabilities caps = new BasicSourceCapabilities();
- Function func = new Function("+", new Expression[] { new ElementSymbol("x"), new ElementSymbol("y") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Function func = new Function("+", new Expression[] { new Constant(1), new Constant(2) }); //$NON-NLS-1$
helpTestSupportsScalar(caps, func, false);
}
@@ -409,14 +410,6 @@
helpTestSupportsScalar(caps, func, true);
}
- // Test where function is unknown
- public void testSupportsScalar5() throws Exception {
- BasicSourceCapabilities caps = new BasicSourceCapabilities();
-
- Function func = new Function("sasquatch", new Expression[] { }); //$NON-NLS-1$
- helpTestSupportsScalar(caps, func, false);
- }
-
public void testSupportsDistinct1() throws Exception {
// Set up metadata
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -62,7 +62,6 @@
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
@@ -5261,7 +5260,7 @@
caps.setFunctionSupport("myrtrim", true); //$NON-NLS-1$
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
processPreparedStatement(sql, expected, dataManager, capFinder,
@@ -5309,7 +5308,7 @@
caps.setFunctionSupport("concat", true); //$NON-NLS-1$
capFinder.addCapabilities("pm4", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
processPreparedStatement(sql, expected, dataManager, capFinder,
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,13 +22,7 @@
package org.teiid.query.resolver;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -57,7 +51,6 @@
import org.teiid.query.function.FunctionDescriptor;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
@@ -1587,7 +1580,7 @@
@Test public void testNamespacedFunction() throws Exception {
String sql = "SELECT namespace.func('e1') FROM vm1.g1 "; //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Query command = (Query) helpParse(sql);
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -46,7 +46,6 @@
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.FakeFunctionMetadataSource;
import org.teiid.query.parser.QueryParser;
@@ -2364,7 +2363,7 @@
}
@Test public void testUDFParse() throws Exception {
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);
Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -302,9 +302,11 @@
List<FunctionTree> udfs = new ArrayList<FunctionTree>();
for (Schema schema : metadataStore.getSchemas().values()) {
vdbMetaData.addModel(FakeMetadataFactory.createModel(schema.getName(), schema.isPhysical()));
- udfs.add(new FunctionTree(new UDFSource(schema.getFunctions().values()), true));
+ if (!schema.getFunctions().isEmpty()) {
+ udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values()), true));
+ }
}
- return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs.toArray(new FunctionTree[udfs.size()]));
+ return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs);
}
/**
Modified: trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -104,7 +104,7 @@
@Override
public FunctionLibrary getFunctionLibrary() {
SystemFunctionManager sfm = new SystemFunctionManager();
- return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods)));
+ return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree("foo", new UDFSource(methods))); //$NON-NLS-1$
}
};
}
Modified: trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -83,11 +83,14 @@
IndexMetadataFactory imf = loadMetadata(vdbURL);
Collection <FunctionMethod> methods = null;
+ Collection<FunctionTree> trees = null;
if (udfFile != null) {
+ String schema = FileUtils.getFilenameWithoutExtension(udfFile.getPath());
methods = FunctionMetadataReader.loadFunctionMethods(udfFile.openStream());
+ trees = Arrays.asList(new FunctionTree(schema, new UDFSource(methods), true));
}
SystemFunctionManager sfm = new SystemFunctionManager();
- vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods), true));
+ vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), trees);
VDB_CACHE.put(vdbURL, vdbmetadata);
return vdbmetadata;
} catch (URISyntaxException e) {
Modified: trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,15 +25,16 @@
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import org.teiid.adminapi.DataPolicy;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.impl.DataPolicyMetadata;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.core.CoreConstants;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
-import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Schema;
@@ -100,8 +101,8 @@
private TransformationMetadata buildTransformationMetaData(VDBMetaData vdb, LinkedHashMap<String, Resource> visibilityMap, MetadataStoreGroup stores, UDFMetaData udf, FunctionTree systemFunctions) {
Collection <FunctionTree> udfs = new ArrayList<FunctionTree>();
if (udf != null) {
- for (Collection<FunctionMethod> methods:udf.getFunctions()) {
- udfs.add(new FunctionTree(new UDFSource(methods), true));
+ for (Map.Entry<String, Collection<FunctionMethod>> entry : udf.getFunctions().entrySet()) {
+ udfs.add(new FunctionTree(entry.getKey(), new UDFSource(entry.getValue()), true));
}
}
@@ -110,7 +111,7 @@
compositeStore.addMetadataStore(s);
}
- TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs.toArray(new FunctionTree[udfs.size()]));
+ TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs);
return metadata;
}
@@ -161,28 +162,23 @@
mergedUDF.addFunctions(this.udf);
}
if (this.stores != null) {
+ //schema scoped source functions - this is only a dynamic vdb concept
for(MetadataStore store:this.stores.getStores()) {
for (Schema schema:store.getSchemas().values()) {
Collection<FunctionMethod> funcs = schema.getFunctions().values();
- for(FunctionMethod func:funcs) {
- func.setNameInSource(func.getName());
- func.setName(schema.getName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- }
- mergedUDF.addFunctions(funcs);
+ mergedUDF.addFunctions(schema.getName(), funcs);
}
}
}
if (this.cmr != null) {
+ //system scoped common source functions
for (ConnectorManager cm:this.cmr.getConnectorManagers().values()) {
List<FunctionMethod> funcs = cm.getPushDownFunctions();
- for(FunctionMethod func:funcs) {
- func.setNameInSource(cm.getTranslatorName()+ AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- func.setName(cm.getModelName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- }
- mergedUDF.addFunctions(funcs);
+ mergedUDF.addFunctions(CoreConstants.SYSTEM_MODEL, funcs);
}
}
if (this.children != null) {
+ //udf model functions - also scoped to the model
for (CompositeVDB child:this.children.values()) {
UDFMetaData funcs = child.getUDF();
if (funcs != null) {
Modified: trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,20 +25,26 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import javax.xml.bind.JAXBException;
import org.jboss.managed.api.annotation.ManagementObject;
import org.jboss.virtual.VirtualFile;
+import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.metadata.FunctionMethod;
+import org.teiid.query.QueryPlugin;
import org.teiid.query.function.metadata.FunctionMetadataReader;
+import org.teiid.query.function.metadata.FunctionMetadataValidator;
+import org.teiid.query.report.ActivityReport;
+import org.teiid.query.report.ReportItem;
import org.teiid.runtime.RuntimePlugin;
@ManagementObject
public class UDFMetaData {
- private Collection<Collection <FunctionMethod>> methods = new ArrayList<Collection<FunctionMethod>>();
-
+ private HashMap<String, Collection <FunctionMethod>> methods = new HashMap<String, Collection<FunctionMethod>>();
private HashMap<String, VirtualFile> files = new HashMap<String, VirtualFile>();
public void addModelFile(VirtualFile file) {
@@ -46,31 +52,45 @@
}
- void buildFunctionModelFile(String name) throws IOException, JAXBException {
+ void buildFunctionModelFile(String name, String path) throws IOException, JAXBException, QueryMetadataException {
for (String f:files.keySet()) {
- if (f.endsWith(name)) {
- name = f;
+ if (f.endsWith(path)) {
+ path = f;
break;
}
}
- VirtualFile file =this.files.get(name);
- if (file != null) {
- this.methods.add(FunctionMetadataReader.loadFunctionMethods(file.openStream()));
- }
- else {
+ VirtualFile file =this.files.get(path);
+ if (file == null) {
throw new IOException(RuntimePlugin.Util.getString("udf_model_not_found", name)); //$NON-NLS-1$
}
+ List<FunctionMethod> udfMethods = FunctionMetadataReader.loadFunctionMethods(file.openStream());
+ ActivityReport<ReportItem> report = new ActivityReport<ReportItem>("UDF load"); //$NON-NLS-1$
+ FunctionMetadataValidator.validateFunctionMethods(udfMethods,report);
+ if(report.hasItems()) {
+ throw new QueryMetadataException(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
+ }
+ this.methods.put(name, udfMethods);
}
- public Collection<Collection <FunctionMethod>> getFunctions(){
+ public Map<String, Collection <FunctionMethod>> getFunctions(){
return this.methods;
}
- public void addFunctions(Collection <FunctionMethod> funcs){
- this.methods.add(funcs);
+ public void addFunctions(String name, Collection <FunctionMethod> funcs){
+ if (funcs.isEmpty()) {
+ return;
+ }
+ Collection <FunctionMethod> old = this.methods.put(name, funcs);
+ if (old != null) {
+ ArrayList<FunctionMethod> combined = new ArrayList<FunctionMethod>(old);
+ combined.addAll(funcs);
+ this.methods.put(name, combined);
+ }
}
public void addFunctions(UDFMetaData funcs){
- this.methods.addAll(funcs.getFunctions());
+ for (Map.Entry<String, Collection<FunctionMethod>> entry : funcs.getFunctions().entrySet()) {
+ addFunctions(entry.getKey(), entry.getValue());
+ }
}
}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -168,7 +168,7 @@
if (path == null) {
throw new DeploymentException(RuntimePlugin.Util.getString("invalid_udf_file", model.getName())); //$NON-NLS-1$
}
- udf.buildFunctionModelFile(path);
+ udf.buildFunctionModelFile(model.getName(), path);
}
}
Modified: trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,7 +116,7 @@
@Test
public void testTranslatorDefinedFunction() throws Exception {
- helpResolve("SELECT bqt1.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
+ helpResolve("SELECT SYS.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
}
@Test
@@ -126,7 +126,7 @@
@Test
public void testFullyQualifiedDuplicate() throws Exception {
- helpResolve("SELECT bqt1.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
+ helpResolve("SELECT SYS.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
}
@Test
14 years, 10 months