[teiid-commits] teiid SVN: r3933 - in branches/7.7.x/engine/src: main/java/org/teiid/query/rewriter and 4 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Mar 12 13:53:36 EDT 2012


Author: shawkins
Date: 2012-03-12 13:53:35 -0400 (Mon, 12 Mar 2012)
New Revision: 3933

Modified:
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
   branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
   branches/7.7.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java
Log:
TEIID-1968 fix for NPE in grouping initialization

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-03-09 20:18:08 UTC (rev 3932)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-03-12 17:53:35 UTC (rev 3933)
@@ -22,17 +22,7 @@
 
 package org.teiid.query.optimizer.relational;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.api.exception.query.QueryPlannerException;
@@ -81,51 +71,11 @@
 import org.teiid.query.sql.LanguageObject;
 import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.LanguageObject.Util;
-import org.teiid.query.sql.lang.CacheHint;
-import org.teiid.query.sql.lang.Command;
-import org.teiid.query.sql.lang.Criteria;
-import org.teiid.query.sql.lang.Delete;
-import org.teiid.query.sql.lang.ExistsCriteria;
-import org.teiid.query.sql.lang.From;
-import org.teiid.query.sql.lang.FromClause;
-import org.teiid.query.sql.lang.GroupBy;
-import org.teiid.query.sql.lang.Insert;
-import org.teiid.query.sql.lang.JoinPredicate;
-import org.teiid.query.sql.lang.JoinType;
-import org.teiid.query.sql.lang.Limit;
-import org.teiid.query.sql.lang.Option;
-import org.teiid.query.sql.lang.OrderBy;
-import org.teiid.query.sql.lang.ProcedureContainer;
-import org.teiid.query.sql.lang.Query;
-import org.teiid.query.sql.lang.QueryCommand;
-import org.teiid.query.sql.lang.Select;
-import org.teiid.query.sql.lang.SetQuery;
-import org.teiid.query.sql.lang.SourceHint;
-import org.teiid.query.sql.lang.StoredProcedure;
-import org.teiid.query.sql.lang.SubqueryContainer;
-import org.teiid.query.sql.lang.SubqueryFromClause;
-import org.teiid.query.sql.lang.TableFunctionReference;
-import org.teiid.query.sql.lang.TargetedCommand;
-import org.teiid.query.sql.lang.TranslatableProcedureContainer;
-import org.teiid.query.sql.lang.UnaryFromClause;
-import org.teiid.query.sql.lang.Update;
-import org.teiid.query.sql.lang.WithQueryCommand;
+import org.teiid.query.sql.lang.*;
 import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
 import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
 import org.teiid.query.sql.proc.TriggerAction;
-import org.teiid.query.sql.symbol.AggregateSymbol;
-import org.teiid.query.sql.symbol.AliasSymbol;
-import org.teiid.query.sql.symbol.Constant;
-import org.teiid.query.sql.symbol.ElementSymbol;
-import org.teiid.query.sql.symbol.Expression;
-import org.teiid.query.sql.symbol.ExpressionSymbol;
-import org.teiid.query.sql.symbol.GroupSymbol;
-import org.teiid.query.sql.symbol.MultipleElementSymbol;
-import org.teiid.query.sql.symbol.Reference;
-import org.teiid.query.sql.symbol.ScalarSubquery;
-import org.teiid.query.sql.symbol.SelectSymbol;
-import org.teiid.query.sql.symbol.SingleElementSymbol;
-import org.teiid.query.sql.symbol.WindowFunction;
+import org.teiid.query.sql.symbol.*;
 import org.teiid.query.sql.util.SymbolMap;
 import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
 import org.teiid.query.sql.visitor.CorrelatedReferenceCollectorVisitor;
@@ -317,6 +267,22 @@
                 Command subCommand = (Command)container.getCommand().clone(); 
                 ArrayList<Reference> correlatedReferences = new ArrayList<Reference>();
                 CorrelatedReferenceCollectorVisitor.collectReferences(subCommand, localGroupSymbols, correlatedReferences);
+                if (node.getType() != NodeConstants.Types.JOIN) {
+                	PlanNode grouping = NodeEditor.findNodePreOrder(node, NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE | NodeConstants.Types.JOIN);
+                	if (grouping != null && !correlatedReferences.isEmpty()) {
+                		SymbolMap map = (SymbolMap) grouping.getProperty(Info.SYMBOL_MAP);
+                		Map<Expression, ElementSymbol> reverseMap = new HashMap<Expression, ElementSymbol>();
+                		for (Map.Entry<ElementSymbol, Expression> entry : map.asMap().entrySet()) {
+							reverseMap.put(entry.getValue(), entry.getKey());
+						}
+                		for (Reference reference : correlatedReferences) {
+							ElementSymbol correlatedGroupingCol = reverseMap.get(reference.getExpression());
+							if (correlatedGroupingCol != null) {
+								reference.setExpression(correlatedGroupingCol);
+							}
+						}
+                	}
+                }
                 ProcessorPlan procPlan = QueryOptimizer.optimizePlan(subCommand, metadata, idGenerator, capFinder, analysisRecord, context);
                 container.getCommand().setProcessorPlan(procPlan);
                 setCorrelatedReferences(container, correlatedReferences);

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2012-03-09 20:18:08 UTC (rev 3932)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2012-03-12 17:53:35 UTC (rev 3933)
@@ -1485,7 +1485,7 @@
      * @return CompareCriteria
      */
     private CompareCriteria simplifyMathematicalCriteria(CompareCriteria criteria)
-    throws TeiidComponentException, TeiidProcessingException{
+    throws TeiidProcessingException{
 
         Expression leftExpr = criteria.getLeftExpression();
         Expression rightExpr = criteria.getRightExpression();

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java	2012-03-09 20:18:08 UTC (rev 3932)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java	2012-03-12 17:53:35 UTC (rev 3933)
@@ -78,7 +78,7 @@
     	this.positional = ref.positional;
     	this.type = ref.type;
     	if (ref.expression != null) {
-    		this.expression = (ElementSymbol)ref.expression.clone();
+    		this.expression = ref.expression.clone();
     	}
     	this.constraint = ref.constraint;
     }
@@ -191,4 +191,9 @@
         return this.positional;
     }
     
+    public void setExpression(ElementSymbol expression) {
+    	assert this.expression != null && !this.positional;
+		this.expression = expression;
+	}
+    
 }

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2012-03-09 20:18:08 UTC (rev 3932)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2012-03-12 17:53:35 UTC (rev 3933)
@@ -57,83 +57,15 @@
 import org.teiid.query.sql.LanguageObject;
 import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.ProcedureReservedWords;
-import org.teiid.query.sql.lang.AlterProcedure;
-import org.teiid.query.sql.lang.AlterTrigger;
-import org.teiid.query.sql.lang.AlterView;
-import org.teiid.query.sql.lang.BatchedUpdateCommand;
-import org.teiid.query.sql.lang.BetweenCriteria;
-import org.teiid.query.sql.lang.Command;
-import org.teiid.query.sql.lang.CompareCriteria;
-import org.teiid.query.sql.lang.CompoundCriteria;
-import org.teiid.query.sql.lang.Create;
-import org.teiid.query.sql.lang.Criteria;
-import org.teiid.query.sql.lang.Delete;
-import org.teiid.query.sql.lang.DependentSetCriteria;
-import org.teiid.query.sql.lang.Drop;
-import org.teiid.query.sql.lang.DynamicCommand;
-import org.teiid.query.sql.lang.ExistsCriteria;
-import org.teiid.query.sql.lang.GroupBy;
-import org.teiid.query.sql.lang.Insert;
-import org.teiid.query.sql.lang.Into;
-import org.teiid.query.sql.lang.IsNullCriteria;
-import org.teiid.query.sql.lang.Limit;
-import org.teiid.query.sql.lang.MatchCriteria;
-import org.teiid.query.sql.lang.NotCriteria;
-import org.teiid.query.sql.lang.Option;
-import org.teiid.query.sql.lang.OrderBy;
-import org.teiid.query.sql.lang.OrderByItem;
-import org.teiid.query.sql.lang.Query;
-import org.teiid.query.sql.lang.QueryCommand;
-import org.teiid.query.sql.lang.SPParameter;
-import org.teiid.query.sql.lang.Select;
-import org.teiid.query.sql.lang.SetClause;
-import org.teiid.query.sql.lang.SetClauseList;
-import org.teiid.query.sql.lang.SetCriteria;
-import org.teiid.query.sql.lang.SetQuery;
-import org.teiid.query.sql.lang.StoredProcedure;
-import org.teiid.query.sql.lang.SubqueryCompareCriteria;
-import org.teiid.query.sql.lang.SubqueryContainer;
-import org.teiid.query.sql.lang.SubqueryFromClause;
-import org.teiid.query.sql.lang.SubquerySetCriteria;
-import org.teiid.query.sql.lang.TextTable;
-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.*;
 import org.teiid.query.sql.lang.SetQuery.Operation;
 import org.teiid.query.sql.lang.XMLTable.XMLColumn;
+import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
 import org.teiid.query.sql.navigator.PreOrderNavigator;
-import org.teiid.query.sql.proc.AssignmentStatement;
-import org.teiid.query.sql.proc.Block;
-import org.teiid.query.sql.proc.BranchingStatement;
-import org.teiid.query.sql.proc.CommandStatement;
-import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
-import org.teiid.query.sql.proc.CriteriaSelector;
-import org.teiid.query.sql.proc.DeclareStatement;
-import org.teiid.query.sql.proc.HasCriteria;
-import org.teiid.query.sql.proc.LoopStatement;
-import org.teiid.query.sql.proc.TranslateCriteria;
-import org.teiid.query.sql.proc.WhileStatement;
+import org.teiid.query.sql.proc.*;
 import org.teiid.query.sql.proc.BranchingStatement.BranchingMode;
 import org.teiid.query.sql.proc.Statement.Labeled;
-import org.teiid.query.sql.symbol.AggregateSymbol;
-import org.teiid.query.sql.symbol.Constant;
-import org.teiid.query.sql.symbol.DerivedColumn;
-import org.teiid.query.sql.symbol.ElementSymbol;
-import org.teiid.query.sql.symbol.Expression;
-import org.teiid.query.sql.symbol.Function;
-import org.teiid.query.sql.symbol.GroupSymbol;
-import org.teiid.query.sql.symbol.QueryString;
-import org.teiid.query.sql.symbol.Reference;
-import org.teiid.query.sql.symbol.ScalarSubquery;
-import org.teiid.query.sql.symbol.SingleElementSymbol;
-import org.teiid.query.sql.symbol.TextLine;
-import org.teiid.query.sql.symbol.WindowFunction;
-import org.teiid.query.sql.symbol.XMLAttributes;
-import org.teiid.query.sql.symbol.XMLElement;
-import org.teiid.query.sql.symbol.XMLForest;
-import org.teiid.query.sql.symbol.XMLNamespaces;
-import org.teiid.query.sql.symbol.XMLParse;
-import org.teiid.query.sql.symbol.XMLQuery;
+import org.teiid.query.sql.symbol.*;
 import org.teiid.query.sql.symbol.AggregateSymbol.Type;
 import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
 import org.teiid.query.sql.visitor.ElementCollectorVisitor;
@@ -761,12 +693,14 @@
         GroupBy groupBy = query.getGroupBy();
         Criteria having = query.getHaving();
         validateNoAggsInClause(groupBy);
+        List<GroupSymbol> correlationGroups = null;
         validateNoAggsInClause(query.getCriteria());
         if (query.getFrom() == null) {
         	validateNoAggsInClause(select);
         	validateNoAggsInClause(query.getOrderBy());
         } else {
         	validateNoAggsInClause(query.getFrom());
+        	correlationGroups = query.getFrom().getGroups();
         }
         
         Set<Expression> groupSymbols = null;
@@ -779,10 +713,14 @@
         LinkedHashSet<Expression> invalidWindowFunctions = new LinkedHashSet<Expression>();
         LinkedList<AggregateSymbol> aggs = new LinkedList<AggregateSymbol>();
         if (having != null) {
+            validateCorrelatedReferences(query, correlationGroups, groupSymbols, having, invalid);
         	AggregateSymbolCollectorVisitor.getAggregates(having, aggs, invalid, null, invalidWindowFunctions, groupSymbols);
         	hasAgg = true;
         }
         for (SingleElementSymbol symbol : select.getProjectedSymbols()) {
+        	if (hasAgg || !aggs.isEmpty()) {
+        		validateCorrelatedReferences(query, correlationGroups, groupSymbols, symbol, invalid);
+        	}
         	AggregateSymbolCollectorVisitor.getAggregates(symbol, aggs, invalid, null, null, groupSymbols);                                            
         }
         if ((!aggs.isEmpty() || hasAgg) && !invalid.isEmpty()) {
@@ -793,6 +731,26 @@
         }
     }
 
+    /**
+     * This validation is more convoluted than needed since it is being run before rewrite/planning.
+     * Ideally we would already have correlated references set on the subqueries.
+     */
+	private void validateCorrelatedReferences(Query query,
+			final List<GroupSymbol> correlationGroups, final Set<Expression> groupingSymbols, LanguageObject object, LinkedHashSet<Expression> invalid) {
+		if (query.getFrom() == null) {
+			return;
+		}
+		ElementCollectorVisitor ecv = new ElementCollectorVisitor(invalid) {
+			public void visit(ElementSymbol obj) {
+				if (obj.isExternalReference() && correlationGroups.contains(obj.getGroupSymbol())
+						 && (groupingSymbols == null || !groupingSymbols.contains(obj))) {
+					super.visit(obj);
+				}
+			}
+		};
+		PreOrPostOrderNavigator.doVisit(object, ecv, PreOrPostOrderNavigator.PRE_ORDER, true);
+	}
+
 	private void validateNoAggsInClause(LanguageObject clause) {
 		if (clause == null) {
         	return;

Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java	2012-03-09 20:18:08 UTC (rev 3932)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java	2012-03-12 17:53:35 UTC (rev 3933)
@@ -504,6 +504,15 @@
     
         process(sql, expected);
     }
+    
+    @Test public void testXmlAggNested() throws Exception {
+        String sql = "SELECT XMLELEMENT(NAME metadata, XMLFOREST(e1), (SELECT XMLAGG(XMLELEMENT(NAME subTypes, XMLFOREST(e1))) FROM pm1.g2 AS b WHERE b.e1 = a.e1)) FROM pm1.g1 AS a where e1 = 'a' GROUP BY e1"; //$NON-NLS-1$
+        
+        List<?>[] expected = new List<?>[] {
+        		Arrays.asList("<metadata><gcol0>a</gcol0><subTypes><e1>a</e1></subTypes><subTypes><e1>a</e1></subTypes><subTypes><e1>a</e1></subTypes></metadata>"),
+        };    
+    
+        process(sql, expected);
+    }
 
-
 }

Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2012-03-09 20:18:08 UTC (rev 3932)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2012-03-12 17:53:35 UTC (rev 3933)
@@ -1957,4 +1957,8 @@
 		helpValidate("select count(distinct e1) over (order by e2) as y from pm1.g1", new String[] {"COUNT(DISTINCT e1) OVER (ORDER BY e2)"}, RealMetadataFactory.example1Cached());
 	}
 	
+	@Test public void testInvalidCorrelation() {
+		helpValidate("SELECT XMLELEMENT(NAME metadata, XMLFOREST(e1 AS objectName), (SELECT XMLAGG(XMLELEMENT(NAME subTypes, XMLFOREST(e1))) FROM pm1.g2 AS b WHERE b.e2 = a.e2)) FROM pm1.g1 AS a GROUP BY e1", new String[] {"a.e2"}, RealMetadataFactory.example1Cached());
+	}
+	
 }



More information about the teiid-commits mailing list