Author: shawkins
Date: 2011-03-01 09:57:25 -0500 (Tue, 01 Mar 2011)
New Revision: 2952
Removed:
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/ReferenceBindingReplacerVisitor.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/BindVariableVisitor.java
Modified:
trunk/client/src/main/java/org/teiid/net/TeiidURL.java
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/QueryUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/SourceNodePlannerVisitor.java
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java
trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/CriteriaTranslatorVisitor.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
Log:
TEIID-1483 consolidating resolving code with designer, allowing named bindings to work in
xml planning logic
Modified: trunk/client/src/main/java/org/teiid/net/TeiidURL.java
===================================================================
--- trunk/client/src/main/java/org/teiid/net/TeiidURL.java 2011-02-28 20:23:19 UTC (rev
2951)
+++ trunk/client/src/main/java/org/teiid/net/TeiidURL.java 2011-03-01 14:57:25 UTC (rev
2952)
@@ -117,7 +117,7 @@
if (StringUtil.startsWithIgnoreCase(serverURL, SECURE_PROTOCOL)) {
usingSSL = true;
} else if (!StringUtil.startsWithIgnoreCase(serverURL, DEFAULT_PROTOCOL)) {
- throw new IllegalArgumentException(INVALID_FORMAT_SERVER);
+ throw new MalformedURLException(INVALID_FORMAT_SERVER);
}
appServerURL = serverURL;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/xml/QueryUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/xml/QueryUtil.java 2011-02-28
20:23:19 UTC (rev 2951)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/xml/QueryUtil.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -25,20 +25,20 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.teiid.api.exception.query.QueryMetadataException;
-import org.teiid.api.exception.query.QueryParserException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.query.QueryPlugin;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
-import org.teiid.query.metadata.TempMetadataAdapter;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.util.ResolverUtil;
@@ -49,11 +49,13 @@
import org.teiid.query.sql.lang.FromClause;
import org.teiid.query.sql.lang.Query;
import org.teiid.query.sql.lang.Select;
+import org.teiid.query.sql.navigator.DeepPreOrderNavigator;
import org.teiid.query.sql.symbol.AllInGroupSymbol;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.Reference;
+import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.sql.visitor.ReferenceCollectorVisitor;
import org.teiid.query.util.CommandContext;
@@ -74,38 +76,21 @@
* @throws QueryPlannerException If an error occurred
* @since 4.3
*/
- static Command getQuery(QueryNode queryNode) throws QueryPlannerException {
+ static Command getQuery(QueryNode queryNode, XMLPlannerEnvironment env) throws
QueryPlannerException {
Command query = queryNode.getCommand();
if (query == null) {
try {
- query = QueryParser.getQueryParser().parseCommand(queryNode.getQuery());
- } catch (QueryParserException e) {
+ query = QueryParser.getQueryParser().parseCommand(queryNode.getQuery());
+ QueryResolver.resolveWithBindingMetadata(query, env.getGlobalMetadata(),
queryNode);
+ } catch (TeiidException e) {
throw new QueryPlannerException(e,
QueryPlugin.Util.getString("ERR.015.004.0054", new
Object[]{queryNode.getGroupName(), queryNode.getQuery()})); //$NON-NLS-1$
- }
+ }
}
return query;
}
/**
- * Resolve a command using the metadata in the planner environment.
- * @param query The query to resolve
- * @param planEnv The planner environment
- * @throws TeiidComponentException
- * @throws QueryPlannerException
- * @since 4.3
- */
- static void resolveQuery(Command query, TempMetadataAdapter metadata)
- throws TeiidComponentException, QueryPlannerException {
- // Run resolver
- try {
- QueryResolver.resolveCommand(query, metadata);
- } catch(QueryResolverException e) {
- throw new QueryPlannerException(e, e.getMessage());
- }
- }
-
- /**
* Rewrite a command using the metadata in the planner environment.
* @param query The query to rewrite
* @param planEnv The planner environment
@@ -177,21 +162,43 @@
throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
QueryNode queryNode = QueryUtil.getQueryNode(groupName,
planEnv.getGlobalMetadata());
- Command command = QueryUtil.getQuery(queryNode);
+ Command command = QueryUtil.getQuery(queryNode, planEnv);
return command;
}
- static void handleBindings(LanguageObject object, QueryNode planNode,
XMLPlannerEnvironment planEnv)
- throws QueryMetadataException, TeiidComponentException {
-
- List parsedBindings = QueryResolver.parseBindings(planNode);
+ static void markBindingsAsNonExternal(LanguageObject object,
+ Collection<ElementSymbol> allBindings) {
+ List<ElementSymbol> elements = new ArrayList<ElementSymbol>();
+ ElementCollectorVisitor visitor = new ElementCollectorVisitor(elements);
+ DeepPreOrderNavigator.doVisit(object, visitor);
+ for (Iterator<ElementSymbol> i = elements.iterator(); i.hasNext();) {
+ ElementSymbol elementSymbol = i.next();
+ if (allBindings.contains(elementSymbol)) {
+ elementSymbol.setIsExternalReference(false);
+ elementSymbol.setMetadataID(null);
+ }
+ }
+ }
- if (!parsedBindings.isEmpty()) {
- //use ReferenceBindingReplacer Visitor
- ReferenceBindingReplacerVisitor.replaceReferences(object, parsedBindings);
- }
- }
+ static Collection<ElementSymbol> getBindingElements(QueryNode queryNode) throws
TeiidComponentException {
+ HashSet<ElementSymbol> set = new HashSet<ElementSymbol>();
+ ElementCollectorVisitor.getElements(QueryResolver.parseBindings(queryNode), set);
+ return set;
+ }
+ static List<ElementSymbol> getBindingsReferences(LanguageObject object,
Collection<ElementSymbol> allBindings) {
+ List<ElementSymbol> elements = new ArrayList<ElementSymbol>();
+ ElementCollectorVisitor visitor = new ElementCollectorVisitor(elements);
+ DeepPreOrderNavigator.doVisit(object, visitor);
+ for (Iterator<ElementSymbol> i = elements.iterator(); i.hasNext();) {
+ ElementSymbol elementSymbol = i.next();
+ if (!elementSymbol.isExternalReference() || !allBindings.contains(elementSymbol)) {
+ i.remove();
+ }
+ }
+ return elements;
+ }
+
static Map createSymbolMap(GroupSymbol oldGroup, final String newGroup, Collection
projectedElements) {
HashMap symbolMap = new HashMap();
symbolMap.put(oldGroup, new GroupSymbol(newGroup));
@@ -205,11 +212,11 @@
}
- static List getReferences(Command command) {
- List boundList = new ArrayList();
+ static List<Reference> getReferences(Command command) {
+ List<Reference> boundList = new ArrayList<Reference>();
- for (Iterator refs = ReferenceCollectorVisitor.getReferences(command).iterator();
refs.hasNext();) {
- Reference ref = (Reference) refs.next();
+ for (Iterator<Reference> refs =
ReferenceCollectorVisitor.getReferences(command).iterator(); refs.hasNext();) {
+ Reference ref = refs.next();
Expression expr = ref.getExpression();
if (!(expr instanceof ElementSymbol)){
continue;
@@ -222,5 +229,6 @@
boundList.add(ref);
}
return boundList;
- }
+ }
+
}
Deleted:
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/ReferenceBindingReplacerVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/ReferenceBindingReplacerVisitor.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/ReferenceBindingReplacerVisitor.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -1,83 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.query.optimizer.xml;
-
-import java.util.List;
-
-import org.teiid.query.sql.LanguageObject;
-import org.teiid.query.sql.navigator.DeepPreOrderNavigator;
-import org.teiid.query.sql.symbol.Expression;
-import org.teiid.query.sql.symbol.Reference;
-import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
-
-
-/**
- * <p>This visitor class will traverse a language object tree, find any Reference
- * objects, and replace them with the corresponding parsed Expression which is the
- * Reference's binding. The List of parsed bindings must contain Expressions, and
- * of course the number and order of the bindings must match up with the number
- * and order of the References that are in the Language Object.</p>
- *
- * <p>The easiest way to use this visitor is to call the static methods which
create
- * the visitor and run it.
- * The public visit() methods should NOT be called directly.</p>
- */
-public class ReferenceBindingReplacerVisitor extends ExpressionMappingVisitor {
-
- private List parsedBindingExpressions;
-
- /**
- * Construct a new visitor with the default collection type, which is a
- * {@link java.util.HashSet}.
- */
- public ReferenceBindingReplacerVisitor(List parsedBindingExpressions) {
- super(null);
- this.parsedBindingExpressions = parsedBindingExpressions;
- }
-
- public Expression replaceExpression(Expression element) {
- if (!(element instanceof Reference)) {
- return element;
- }
-
- Reference reference = (Reference)element;
-
- return (Expression)parsedBindingExpressions.get(reference.getIndex());
- }
-
- /**
- * Helper to quickly get the references from obj in the references collection
- * @param obj Language object
- * @param elements Collection to collect references in
- */
- public static final void replaceReferences(LanguageObject obj, List
parsedBindingExpressions) {
- if (parsedBindingExpressions == null || parsedBindingExpressions.isEmpty()) {
- return;
- }
-
- ReferenceBindingReplacerVisitor visitor = new
ReferenceBindingReplacerVisitor(parsedBindingExpressions);
- DeepPreOrderNavigator.doVisit(obj, visitor);
- }
-
-}
-
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/SourceNodePlannerVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/SourceNodePlannerVisitor.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/SourceNodePlannerVisitor.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -31,7 +31,6 @@
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.TeiidRuntimeException;
import org.teiid.query.mapping.relational.QueryNode;
@@ -56,7 +55,6 @@
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
-import org.teiid.query.sql.visitor.ReferenceCollectorVisitor;
import org.teiid.query.sql.visitor.SQLStringVisitor;
@@ -112,23 +110,23 @@
//create the command off of the unresolved group symbol
Query baseQuery = QueryUtil.wrapQuery(new UnaryFromClause(new
GroupSymbol(newGroup)), newGroup);
baseQuery.getSelect().clearSymbols();
- for (Iterator i = ResolverUtil.resolveElementsInGroup(groupSymbol,
planEnv.getGlobalMetadata()).iterator(); i.hasNext();) {
- SingleElementSymbol ses = (SingleElementSymbol)i.next();
+ for (Iterator<ElementSymbol> i =
ResolverUtil.resolveElementsInGroup(groupSymbol, planEnv.getGlobalMetadata()).iterator();
i.hasNext();) {
+ ElementSymbol ses = i.next();
baseQuery.getSelect().addSymbol(new ElementSymbol(newGroup +
SingleElementSymbol.SEPARATOR + ses.getShortName()));
}
rsInfo.setCommand(baseQuery);
QueryNode modifiedNode = QueryUtil.getQueryNode(newGroup,
planEnv.getGlobalMetadata());
- Command command = QueryUtil.getQuery(modifiedNode);
+ Command command = QueryUtil.getQuery(modifiedNode, planEnv);
MappingSourceNode parent = sourceNode.getParentSourceNode();
-
+ Collection<ElementSymbol> bindings =
QueryUtil.getBindingElements(modifiedNode);
// root source nodes do not have any inputset criteria on them; so there is
no use in
// going through the raising the criteria.
// if the original query is not a select.. we are out of luck. we can expand
on this later
// versions. make ure bindings are only to parent.
- if (parent == null || !canRaiseInputset(command) ||
!areBindingsOnlyToNode(modifiedNode, parent)) {
+ if (parent == null || !canRaiseInputset(command, bindings) ||
!areBindingsOnlyToNode(modifiedNode, parent)) {
return;
}
@@ -136,18 +134,16 @@
// criteria.
Query transformationQuery = (Query)command;
- QueryUtil.resolveQuery(transformationQuery, planEnv.getGlobalMetadata());
-
Criteria criteria = transformationQuery.getCriteria();
Criteria nonInputsetCriteria = null;
Criteria inputSetCriteria = null;
- for (Iterator i = Criteria.separateCriteriaByAnd(criteria).iterator();
i.hasNext();) {
- Criteria conjunct = (Criteria) i.next();
+ for (Iterator<Criteria> i =
Criteria.separateCriteriaByAnd(criteria).iterator(); i.hasNext();) {
+ Criteria conjunct = i.next();
// collect references in the criteria; if there are references; then this
is
// set by inputset criteria
- Collection references =
ReferenceCollectorVisitor.getReferences(conjunct);
+ Collection<ElementSymbol> references =
QueryUtil.getBindingsReferences(conjunct, bindings);
if (references.isEmpty()) {
nonInputsetCriteria = Criteria.combineCriteria(nonInputsetCriteria,
conjunct);
}
@@ -176,9 +172,7 @@
QueryNode relationalNode = new QueryNode(newGroup,
SQLStringVisitor.getSQLString(transformationQuery));
planEnv.addQueryNodeToMetadata(newGroupSymbol.getMetadataID(),
relationalNode);
- // this is the simple form of the planned query preplan stage. set the
command
- // with newly found criteria.
- QueryUtil.handleBindings(inputSetCriteria, modifiedNode, planEnv);
+ QueryUtil.markBindingsAsNonExternal(inputSetCriteria, bindings);
baseQuery.setCriteria(inputSetCriteria);
rsInfo.setCriteriaRaised(true);
@@ -232,7 +226,7 @@
* set names in a mapping document.
*/
private GroupSymbol createAlternateGroup(GroupSymbol oldSymbol, MappingSourceNode
sourceNode)
- throws QueryMetadataException, TeiidComponentException, QueryResolverException,
QueryPlannerException {
+ throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
// get elements in the old group
List elements = ResolverUtil.resolveElementsInGroup(oldSymbol,
planEnv.getGlobalMetadata());
@@ -277,7 +271,7 @@
}
ElementSymbol es = (ElementSymbol)ses;
if (!useName) {
- bindings.add(sourceNode.getMappedSymbol(es).getName());
+ bindings.add(sourceNode.getMappedSymbol(es).toString());
} else {
bindings.add(new AliasSymbol(name,
sourceNode.getMappedSymbol(es)).toString());
}
@@ -286,7 +280,7 @@
}
}
- private boolean canRaiseInputset(Command command) {
+ private boolean canRaiseInputset(Command command, Collection<ElementSymbol>
bindings) throws TeiidComponentException {
// check to see if this is query.
if (!(command instanceof Query)) {
return false;
@@ -303,7 +297,7 @@
//just throw away order by
query.setOrderBy(null);
- Collection references = ReferenceCollectorVisitor.getReferences(query);
+ List<ElementSymbol> references = QueryUtil.getBindingsReferences(query,
bindings);
query.setCriteria(crit);
@@ -321,17 +315,21 @@
throws QueryMetadataException, TeiidComponentException {
String groupName = newGroupSymbol.getName();
- Collection elementsInCriteria = ElementCollectorVisitor.getElements(criteria,
true);
+ Collection<ElementSymbol> elementsInCriteria =
ElementCollectorVisitor.getElements(criteria, true);
Map mappedElements = new HashMap();
List projectedSymbols = transformationQuery.getProjectedSymbols();
boolean addedProjectedSymbol = false;
- for (Iterator i = elementsInCriteria.iterator(); i.hasNext();) {
+ for (Iterator<ElementSymbol> i = elementsInCriteria.iterator();
i.hasNext();) {
- final ElementSymbol symbol = (ElementSymbol)i.next();
+ final ElementSymbol symbol = i.next();
+ if (symbol.isExternalReference()) {
+ continue;
+ }
+
if (projectedSymbols.contains(symbol)) {
mappedElements.put(symbol, new ElementSymbol(groupName +
ElementSymbol.SEPARATOR + symbol.getShortName()));
continue;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -53,6 +53,7 @@
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.relational.RelationalNode;
import org.teiid.query.processor.relational.RelationalPlan;
+import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
import org.teiid.query.sql.lang.Command;
@@ -203,13 +204,13 @@
}
static void prepareQuery(MappingSourceNode sourceNode, XMLPlannerEnvironment planEnv,
QueryCommand rsQuery)
- throws TeiidComponentException, QueryPlannerException {
+ throws TeiidComponentException, QueryResolverException {
Collection externalGroups = getExternalGroups(sourceNode);
rsQuery.setExternalGroupContexts(new GroupContext(null, externalGroups));
- QueryUtil.resolveQuery(rsQuery, planEnv.getGlobalMetadata());
+ QueryResolver.resolveCommand(rsQuery, planEnv.getGlobalMetadata());
}
private static Collection getExternalGroups(MappingSourceNode sourceNode) {
@@ -291,7 +292,7 @@
ResultSetInfo childRsInfo = rsNode.getResultSetInfo();
QueryNode planNode = QueryUtil.getQueryNode(childRsInfo.getResultSetName(),
planEnv.getGlobalMetadata());
- Command command = QueryUtil.getQuery(planNode);
+ Command command = QueryUtil.getQuery(planNode, planEnv);
String inlineViewName =
planEnv.getAliasName(childRsInfo.getResultSetName());
@@ -338,8 +339,6 @@
throw new
QueryPlannerException(QueryPlugin.Util.getString("XMLQueryPlanner.cannot_plan",
rsInfo.getCriteria())); //$NON-NLS-1$
}
- QueryUtil.handleBindings(command, planNode, planEnv);
-
Query subQuery = QueryUtil.wrapQuery(new SubqueryFromClause(inlineViewName,
command), inlineViewName);
currentQuery.setCriteria(Criteria.combineCriteria(currentQuery.getCriteria(),
new ExistsCriteria(subQuery)));
@@ -359,13 +358,13 @@
QueryUtil.rewriteQuery(contextQuery, planEnv.getGlobalMetadata(),
planEnv.context);
//selectively replace correlated references with their actual element
symbols
- List bindings = QueryUtil.getReferences(contextQuery);
+ List<Reference> bindings = QueryUtil.getReferences(contextQuery);
QueryNode modifiedNode = new QueryNode(rsInfo.getResultSetName(), null);
modifiedNode.setCommand(contextQuery);
- for (Iterator i = bindings.iterator(); i.hasNext();) {
- Reference ref = (Reference)i.next();
+ for (Iterator<Reference> i = bindings.iterator(); i.hasNext();) {
+ Reference ref = i.next();
modifiedNode.addBinding(ref.getExpression().toString());
}
@@ -393,9 +392,10 @@
* @param groupName
* @param planEnv
* @return {@link GroupSymbol} the temptable which has been planned.
+ * @throws QueryResolverException
*/
static void planStagingTable(String groupName, XMLPlannerEnvironment planEnv)
- throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+ throws QueryPlannerException, QueryMetadataException, TeiidComponentException,
QueryResolverException {
ResultSetInfo rsInfo = planEnv.getStagingTableResultsInfo(groupName);
@@ -410,9 +410,10 @@
* This method takes given query and adds the "into" symbol to query and
resoves it
* and registers it with planner env as the staging table. Also, builds a unload
query
* to unload the staging table.
+ * @throws QueryResolverException
*/
static boolean planStagaingQuery(boolean implicit, String srcGroupName, String
stageGroupName, Query query, XMLPlannerEnvironment planEnv)
- throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+ throws QueryPlannerException, QueryMetadataException, TeiidComponentException,
QueryResolverException {
GroupSymbol srcGroup = QueryUtil.createResolvedGroup(srcGroupName,
planEnv.getGlobalMetadata());
@@ -421,7 +422,7 @@
query.setInto(new Into(intoGroupSymbol));
- QueryUtil.resolveQuery(query, planEnv.getGlobalMetadata());
+ QueryResolver.resolveCommand(query, planEnv.getGlobalMetadata());
Command cmd = QueryUtil.rewriteQuery(query, planEnv.getGlobalMetadata(),
planEnv.context);
@@ -493,7 +494,7 @@
String unloadName = planEnv.unLoadResultName(stageGroupName);
ResultSetInfo rsUnloadInfo = planEnv.getStagingTableResultsInfo(unloadName);
Command command = wrapStagingTableUnloadQuery(intoGroupSymbol);
- QueryUtil.resolveQuery(command, planEnv.getGlobalMetadata());
+ QueryResolver.resolveCommand(command, planEnv.getGlobalMetadata());
command = QueryUtil.rewriteQuery(command, planEnv.getGlobalMetadata(),
planEnv.context);
plan = optimizePlan(command, planEnv);
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -26,6 +26,7 @@
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.TeiidRuntimeException;
import org.teiid.query.mapping.relational.QueryNode;
@@ -85,7 +86,7 @@
}
static boolean stagePlannedQuery(MappingSourceNode sourceNode, XMLPlannerEnvironment
planEnv)
- throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+ throws QueryPlannerException, QueryMetadataException, TeiidComponentException,
QueryResolverException {
Option option = planEnv.xmlCommand.getOption();
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java 2011-02-28
20:23:19 UTC (rev 2951)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -56,7 +56,6 @@
import org.teiid.query.resolver.command.UpdateProcedureResolver;
import org.teiid.query.resolver.command.UpdateResolver;
import org.teiid.query.resolver.command.XMLQueryResolver;
-import org.teiid.query.resolver.util.BindVariableVisitor;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.ProcedureReservedWords;
@@ -69,12 +68,15 @@
import org.teiid.query.sql.lang.Query;
import org.teiid.query.sql.lang.SubqueryContainer;
import org.teiid.query.sql.lang.UnaryFromClause;
+import org.teiid.query.sql.navigator.DeepPostOrderNavigator;
import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
import org.teiid.query.sql.symbol.AliasSymbol;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.Reference;
import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.validator.ValidationVisitor;
@@ -147,8 +149,7 @@
case Command.TYPE_QUERY:
QueryNode queryNode =
metadata.getVirtualPlan(metadata.getGroupID(container.getCanonicalName()));
- addBindingMetadata(currentCommand, metadata, queryNode);
- break;
+ return resolveWithBindingMetadata(currentCommand, metadata, queryNode);
case Command.TYPE_INSERT:
case Command.TYPE_UPDATE:
case Command.TYPE_DELETE:
@@ -158,15 +159,24 @@
return resolveCommand(currentCommand, metadata, true);
}
- static void addBindingMetadata(Command currentCommand,
+ /**
+ * Bindings are a poor mans input parameters. They are represented in legacy metadata
+ * by ElementSymbols and placed positionally into the command or by alias symbols
+ * and matched by names. After resolving bindings will be replaced with their
+ * referenced symbols (input names will not be used) and those symbols will
+ * be marked as external references.
+ */
+ public static TempMetadataStore resolveWithBindingMetadata(Command currentCommand,
QueryMetadataInterface metadata, QueryNode queryNode)
throws TeiidComponentException, QueryResolverException {
+ Map<ElementSymbol, ElementSymbol> symbolMap = null;
if (queryNode.getBindings() != null && queryNode.getBindings().size() > 0)
{
+ symbolMap = new HashMap<ElementSymbol, ElementSymbol>();
// GroupSymbol (name form) for InputSet
GroupSymbol inputSetSymbol = new GroupSymbol(ProcedureReservedWords.INPUT);
// Create ElementSymbols for each InputParameter
- List<ElementSymbol> elements = new
ArrayList<ElementSymbol>(queryNode.getBindings().size());
+ final List<ElementSymbol> elements = new
ArrayList<ElementSymbol>(queryNode.getBindings().size());
boolean positional = true;
for (SingleElementSymbol ses : parseBindings(queryNode)) {
String name = ses.getName();
@@ -176,13 +186,28 @@
}
ElementSymbol elementSymbol = (ElementSymbol)ses;
ResolverVisitor.resolveLanguageObject(elementSymbol, metadata);
+ elementSymbol.setIsExternalReference(true);
if (!positional) {
+ symbolMap.put(new ElementSymbol(ProcedureReservedWords.INPUT +
ElementSymbol.SEPARATOR + name), (ElementSymbol)elementSymbol.clone());
elementSymbol.setName(name);
}
elements.add(elementSymbol);
}
if (positional) {
- BindVariableVisitor.bindReferences(currentCommand, elements);
+ ExpressionMappingVisitor emv = new ExpressionMappingVisitor(null) {
+ @Override
+ public Expression replaceExpression(Expression element) {
+ if (!(element instanceof Reference)) {
+ return element;
+ }
+ Reference ref = (Reference)element;
+ if (!ref.isPositional()) {
+ return ref;
+ }
+ return (ElementSymbol)elements.get(ref.getIndex()).clone();
+ }
+ };
+ DeepPostOrderNavigator.doVisit(currentCommand, emv);
} else {
TempMetadataStore rootExternalStore = new TempMetadataStore();
rootExternalStore.addTempGroup(inputSetSymbol.getName(), elements);
@@ -196,6 +221,13 @@
}
}
}
+ TempMetadataStore result = resolveCommand(currentCommand, metadata, true);
+ if (symbolMap != null && !symbolMap.isEmpty()) {
+ ExpressionMappingVisitor emv = new ExpressionMappingVisitor(symbolMap);
+ emv.setClone(true);
+ DeepPostOrderNavigator.doVisit(currentCommand, emv);
+ }
+ return result;
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -110,8 +110,12 @@
// for this map will either be the String names of the parameters or
// the Integer indices, as entered in the user query
Map<Object, Expression> inputExpressions = new HashMap<Object,
Expression>();
+ int adjustIndex = 0;
for (SPParameter param : oldParams) {
if(param.getExpression() == null) {
+ if (param.getParameterType() == SPParameter.RESULT_SET) {
+ adjustIndex--; //If this was already resolved, just pretend the result set
param doesn't exist
+ }
continue;
}
if (namedParameters && param.getParameterType() !=
SPParameter.RETURN_VALUE) {
@@ -119,7 +123,7 @@
throw new
QueryResolverException(QueryPlugin.Util.getString("ExecResolver.duplicate_named_params",
param.getName().toUpperCase())); //$NON-NLS-1$
}
} else {
- inputExpressions.put(param.getIndex(), param.getExpression());
+ inputExpressions.put(param.getIndex() + adjustIndex,
param.getExpression());
}
}
Deleted:
trunk/engine/src/main/java/org/teiid/query/resolver/util/BindVariableVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/util/BindVariableVisitor.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/util/BindVariableVisitor.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -1,109 +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.resolver.util;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.teiid.client.metadata.ParameterInfo;
-import org.teiid.core.util.ArgCheck;
-import org.teiid.query.QueryPlugin;
-import org.teiid.query.sql.LanguageObject;
-import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.lang.SPParameter;
-import org.teiid.query.sql.lang.StoredProcedure;
-import org.teiid.query.sql.navigator.DeepPreOrderNavigator;
-import org.teiid.query.sql.symbol.ElementSymbol;
-import org.teiid.query.sql.symbol.Reference;
-
-
-/**
- * <p>Given a LanguageObject containing References and the List of String binding
- * expressions from a query transformation, this visitor will parse and resolve
- * each binding and set the resolved expression on the appropriate Reference,
- * making sure to match up the correct binding with the correct Reference.
- * The Reference is fully resolved after this happens.</p>
- *
- * <p>Optionally, a Map can be built up which maps the String virtual group to
- * a List of Reference objects which have bindings to an element of the
- * virtual group key. This may be useful to have on hand the Reference objects
- * which are dependent on the changing tuples of a virtual group during query
- * processing.</p>
- */
-public class BindVariableVisitor extends LanguageVisitor {
-
- private List<ElementSymbol> bindings;
-
- /**
- * Constructor
- * @param bindings List of String binding expressions from query
- * transformation node
- */
- public BindVariableVisitor(List<ElementSymbol> bindings) {
- ArgCheck.isNotNull(bindings, QueryPlugin.Util.getString("ERR.015.008.0049"));
//$NON-NLS-1$
-
- this.bindings = bindings;
- }
-
- /**
- * Visit a Reference object and bind it based on the bindings
- * @see org.teiid.query.sql.LanguageVisitor#visit(Reference)
- */
- public void visit(Reference obj) {
- bindReference(obj);
- }
-
- private void bindReference(Reference obj) {
- int index = obj.getIndex();
-
- ElementSymbol binding = bindings.get(index);
- obj.setExpression(binding);
- }
-
- public void visit(StoredProcedure storedProcedure){
- //collect reference for physical stored procedure
- Iterator<SPParameter> paramsIter =
storedProcedure.getParameters().iterator();
- while(paramsIter.hasNext()){
- SPParameter param = paramsIter.next();
- if(param.getParameterType() == ParameterInfo.IN || param.getParameterType()
== ParameterInfo.INOUT){
- if(param.getExpression() instanceof Reference){
- bindReference((Reference)param.getExpression());
- }
- }
- }
- }
-
- /**
- * Convenient static method for using this visitor
- * @param obj LanguageObject which has References to be bound
- * @param bindings List of String binding expressions from query
- * transformation node
- * @param boundReferencesMap Map to be filled with String group name to List of
References
- */
- public static void bindReferences(LanguageObject obj, List<ElementSymbol>
bindings) {
-
- BindVariableVisitor visitor = new BindVariableVisitor(bindings);
- DeepPreOrderNavigator.doVisit(obj, visitor);
- }
-
-}
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/visitor/CriteriaTranslatorVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/visitor/CriteriaTranslatorVisitor.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/main/java/org/teiid/query/sql/visitor/CriteriaTranslatorVisitor.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -28,8 +28,6 @@
import java.util.LinkedList;
import java.util.Map;
-import net.sf.saxon.query.QueryReader;
-
import org.teiid.core.util.Assertion;
import org.teiid.query.rewriter.QueryRewriter;
import org.teiid.query.sql.lang.AbstractSetCriteria;
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-28
20:23:19 UTC (rev 2951)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -1102,11 +1102,11 @@
"SELECT 1 FROM pm1.g2" } ); //$NON-NLS-1$
}
- @Test public void testPushMatchCritWithReference() {
+ @Test public void testPushMatchCritWithReference() throws Exception {
List bindings = new ArrayList();
bindings.add("pm1.g2.e1"); //$NON-NLS-1$
helpPlan("select e1 FROM pm1.g1 WHERE e1 LIKE ?", example1(), bindings,
null, //$NON-NLS-1$
- new String[] { "SELECT e1 FROM pm1.g1 WHERE e1 LIKE ?" }, true );
//$NON-NLS-1$
+ new String[] { "SELECT g_0.e1 FROM pm1.g1 AS g_0 WHERE g_0.e1 LIKE
PM1.G2.e1" }, ComparisonMode.EXACT_COMMAND_STRING ); //$NON-NLS-1$
}
@Test public void testDefect6517() {
Modified: trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java 2011-02-28
20:23:19 UTC (rev 2951)
+++
trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -157,9 +157,9 @@
FakeMetadataObject rs =
FakeMetadataFactory.createVirtualGroup("xmltest.group.items", xmltest, rsQuery);
//$NON-NLS-1$
// Created 2nd virtual group w/ nested result set & binding
- QueryNode rsQuery2 = new QueryNode("xmltest.suppliers", "SELECT
concat(stock.suppliers.supplierNum, '') as supplierNum, supplierName,
supplierZipCode FROM stock.suppliers, stock.item_supplier WHERE
stock.suppliers.supplierNum = stock.item_supplier.supplierNum AND
stock.item_supplier.itemNum = ?"); //$NON-NLS-1$ //$NON-NLS-2$
+ QueryNode rsQuery2 = new QueryNode("xmltest.suppliers", "SELECT
concat(stock.suppliers.supplierNum, '') as supplierNum, supplierName,
supplierZipCode FROM stock.suppliers, stock.item_supplier WHERE
stock.suppliers.supplierNum = stock.item_supplier.supplierNum AND
stock.item_supplier.itemNum = input.x"); //$NON-NLS-1$ //$NON-NLS-2$
//QueryNode rsQuery2 = new QueryNode("xmltest.suppliers", "SELECT
stock.suppliers.supplierNum, supplierName, supplierZipCode FROM stock.suppliers,
stock.item_supplier WHERE stock.suppliers.supplierNum = stock.item_supplier.supplierNum
AND stock.item_supplier.itemNum = ?");
- rsQuery2.addBinding("xmltest.group.items.itemNum"); //$NON-NLS-1$
+ rsQuery2.addBinding("xmltest.group.items.itemNum as x"); //$NON-NLS-1$
FakeMetadataObject rs2 =
FakeMetadataFactory.createVirtualGroup("xmltest.suppliers", xmltest, rsQuery2);
//$NON-NLS-1$
// Created virtual group w/ nested result set & binding
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-28
20:23:19 UTC (rev 2951)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-03-01
14:57:25 UTC (rev 2952)
@@ -90,7 +90,6 @@
import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.sql.visitor.FunctionCollectorVisitor;
import org.teiid.query.sql.visitor.GroupCollectorVisitor;
-import org.teiid.query.sql.visitor.ReferenceCollectorVisitor;
import org.teiid.query.unittest.FakeMetadataFacade;
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.unittest.FakeMetadataObject;
@@ -235,8 +234,7 @@
QueryNode qn = new QueryNode("x", sql);
qn.setBindings(bindings);
// resolve
- QueryResolver.addBindingMetadata(command, metadata, qn);
- QueryResolver.resolveCommand(command, metadata);
+ QueryResolver.resolveWithBindingMetadata(command, metadata, qn);
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(command, vis);
@@ -831,28 +829,30 @@
helpCheckFrom(resolvedQuery, new String[] { "pm1.g1" }); //$NON-NLS-1$
helpCheckSelect(resolvedQuery, new String[] { "pm1.g1.e1",
"expr" }); //$NON-NLS-1$ //$NON-NLS-2$
helpCheckElements(resolvedQuery.getCriteria(),
- new String[] { "pm1.g1.e1" }, //$NON-NLS-1$
- new String[] { "pm1.g1.e1" } ); //$NON-NLS-1$
+ new String[] { "pm1.g1.e1", "pm1.g2.e2" }, //$NON-NLS-1$
+ new String[] { "pm1.g1.e1", "pm1.g2.e2" } );
//$NON-NLS-1$
}
@Test public void testResolveParametersInsert() throws Exception {
- List bindings = new ArrayList();
- bindings.add("pm1.g2.e1"); //$NON-NLS-1$
+ List<String> bindings = Arrays.asList("pm1.g2.e1"); //$NON-NLS-1$
helpResolveWithBindings("INSERT INTO pm1.g1 (e1) VALUES (?)", metadata,
bindings); //$NON-NLS-1$
}
@Test public void testResolveParametersExec() throws Exception {
- List bindings = new ArrayList();
- bindings.add("pm1.g2.e1"); //$NON-NLS-1$
+ List<String> bindings = Arrays.asList("pm1.g2.e1");
//$NON-NLS-1$
Query resolvedQuery = (Query)helpResolveWithBindings("SELECT * FROM (exec
pm1.sq2(?)) as a", metadata, bindings); //$NON-NLS-1$
- //verify the type of the reference is resolved
- List refs = ReferenceCollectorVisitor.getReferences(resolvedQuery);
- Reference ref = (Reference)refs.get(0);
- assertNotNull(ref.getType());
+ StoredProcedure sp =
(StoredProcedure)((SubqueryFromClause)resolvedQuery.getFrom().getClauses().get(0)).getCommand();
+ assertEquals(String.class,
sp.getInputParameters().get(0).getExpression().getType());
}
+
+ @Test public void testResolveParametersExecNamed() throws Exception {
+ List<String> bindings = Arrays.asList("pm1.g2.e1 as x");
//$NON-NLS-1$
+
+ helpResolveWithBindings("SELECT * FROM (exec pm1.sq2(input.x)) as a",
metadata, bindings); //$NON-NLS-1$
+ }
@Test public void testUseNonExistentAlias() {
helpResolveException("SELECT portfoliob.e1 FROM ((pm1.g1 AS portfoliob JOIN
pm1.g2 AS portidentb ON portfoliob.e1 = portidentb.e1) RIGHT OUTER JOIN pm1.g3 AS
identifiersb ON portidentb.e1 = 'ISIN' and portidentb.e2 = identifiersb.e2) RIGHT
OUTER JOIN pm1.g1 AS issuesb ON a.identifiersb.e1 = issuesb.e1"); //$NON-NLS-1$