[teiid-commits] teiid SVN: r2952 - in trunk: engine/src/main/java/org/teiid/query/optimizer/xml and 7 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Tue Mar 1 09:57:26 EST 2011


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$



More information about the teiid-commits mailing list