[teiid-commits] teiid SVN: r3010 - in trunk/engine/src: main/java/org/teiid/query/processor/relational and 4 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Sat Mar 19 10:32:44 EDT 2011
Author: shawkins
Date: 2011-03-19 10:32:44 -0400 (Sat, 19 Mar 2011)
New Revision: 3010
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/util/VariableContext.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
Log:
TEIID-1497 adding determinism checks and cleaning up correlation logic
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -76,6 +76,7 @@
import org.teiid.query.sql.symbol.XMLSerialize;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.EvaluatableVisitor;
+import org.teiid.query.sql.visitor.FunctionCollectorVisitor;
import org.teiid.query.sql.visitor.GroupCollectorVisitor;
@@ -386,7 +387,7 @@
try {
if(!this.caps.supportsCapability(Capability.QUERY_SUBQUERIES_SCALAR)
|| validateSubqueryPushdown(obj, modelID, metadata, capFinder, analysisRecord) == null) {
- if (obj.getCommand().getCorrelatedReferences() == null) {
+ if (obj.getCommand().getCorrelatedReferences() == null && !FunctionCollectorVisitor.isNonDeterministic(obj.getCommand())) {
obj.setShouldEvaluate(true);
} else {
markInvalid(obj.getCommand(), !this.caps.supportsCapability(Capability.QUERY_SUBQUERIES_SCALAR)?
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -32,7 +32,6 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
-import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -47,7 +46,6 @@
import org.teiid.query.sql.lang.OrderByItem;
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.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
@@ -355,11 +353,8 @@
return false;
}
// TEIID-16: We do not want to merge a non-deterministic scalar function
- Collection<Function> functions = FunctionCollectorVisitor.getFunctions(symbol, true, true);
- for (Function function : functions) {
- if ( function.getFunctionDescriptor().getDeterministic() == Determinism.NONDETERMINISTIC) {
- return false;
- }
+ if (FunctionCollectorVisitor.isNonDeterministic(symbol)) {
+ return false;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -30,6 +30,7 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.DataTypeManager;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.processor.BatchCollector;
import org.teiid.query.processor.ProcessorDataManager;
@@ -39,8 +40,11 @@
import org.teiid.query.sql.symbol.ContextReference;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.ScalarSubquery;
+import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.util.ValueIterator;
import org.teiid.query.sql.util.VariableContext;
+import org.teiid.query.sql.visitor.FunctionCollectorVisitor;
import org.teiid.query.util.CommandContext;
@@ -54,8 +58,10 @@
QueryProcessor processor;
BatchCollector collector;
boolean done;
- List<?> tuple;
ProcessorPlan plan;
+ boolean nonDeterministic;
+ List<Object> refValues;
+ boolean comparable = true;
void close() {
if (processor == null) {
@@ -73,13 +79,13 @@
//processing state
private Map<String, SubqueryState> subqueries = new HashMap<String, SubqueryState>();
-
+
public SubqueryAwareEvaluator(Map elements, ProcessorDataManager dataMgr,
CommandContext context, BufferManager manager) {
super(elements, dataMgr, context);
this.manager = manager;
}
-
+
public void reset() {
for (SubqueryState subQueryState : subqueries.values()) {
subQueryState.plan.reset();
@@ -102,26 +108,48 @@
if (state == null) {
state = new SubqueryState();
state.plan = container.getCommand().getProcessorPlan().clone();
+ if (container instanceof ScalarSubquery) {
+ state.nonDeterministic = FunctionCollectorVisitor.isNonDeterministic(container.getCommand());
+ }
+ if (container.getCommand().getCorrelatedReferences() != null) {
+ for (ElementSymbol es : container.getCommand().getCorrelatedReferences().getKeys()) {
+ if (DataTypeManager.isNonComparable(DataTypeManager.getDataTypeName(es.getType()))) {
+ state.comparable = false;
+ break;
+ }
+ }
+ }
this.subqueries.put(key, state);
}
- if ((tuple == null && state.tuple != null) || (tuple != null && !tuple.equals(state.tuple))) {
- if (container.getCommand().getCorrelatedReferences() != null) {
- state.close();
+ SymbolMap correlatedRefs = container.getCommand().getCorrelatedReferences();
+ VariableContext currentContext = null;
+ boolean shouldClose = state.done && state.nonDeterministic;
+ if (correlatedRefs != null) {
+ currentContext = new VariableContext();
+ for (Map.Entry<ElementSymbol, Expression> entry : container.getCommand().getCorrelatedReferences().asMap().entrySet()) {
+ currentContext.setValue(entry.getKey(), evaluate(entry.getValue(), tuple));
}
- state.tuple = tuple;
+ List<Object> refValues = currentContext.getLocalValues();
+ if (!refValues.equals(state.refValues)) {
+ state.refValues = refValues;
+ shouldClose = true;
+ }
}
+ if (shouldClose) {
+ //if (state.done && state.comparable) {
+ //cache
+ //} else {
+ state.close();
+ //}
+ }
if (!state.done) {
if (state.processor == null) {
CommandContext subContext = context.clone();
state.plan.reset();
state.processor = new QueryProcessor(state.plan, subContext, manager, this.dataMgr);
- if (container.getCommand().getCorrelatedReferences() != null) {
- VariableContext currentContext = new VariableContext();
- for (Map.Entry<ElementSymbol, Expression> entry : container.getCommand().getCorrelatedReferences().asMap().entrySet()) {
- currentContext.setValue(entry.getKey(), evaluate(entry.getValue(), tuple));
- }
- state.processor.getContext().pushVariableContext(currentContext);
- }
+ if (currentContext != null) {
+ state.processor.getContext().pushVariableContext(currentContext);
+ }
state.collector = state.processor.createBatchCollector();
}
state.done = true;
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -55,7 +55,6 @@
import org.teiid.core.util.Assertion;
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.SQLConstants.NonReserved;
-import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.function.FunctionDescriptor;
@@ -162,7 +161,6 @@
import org.teiid.query.sql.visitor.EvaluatableVisitor;
import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.FunctionCollectorVisitor;
-import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.sql.visitor.EvaluatableVisitor.EvaluationLevel;
import org.teiid.query.util.CommandContext;
import org.teiid.query.validator.UpdateValidator.UpdateInfo;
@@ -750,11 +748,8 @@
} else if (query.getSelect().isDistinct()) {
for (SingleElementSymbol projectSymbol : query.getSelect().getProjectedSymbols()) {
Expression ex = SymbolMap.getExpression(projectSymbol);
- Collection<Function> functions = FunctionCollectorVisitor.getFunctions(ex, true, false);
- for (Function function : functions) {
- if ( function.getFunctionDescriptor().getDeterministic() == Determinism.NONDETERMINISTIC) {
- return true;
- }
+ if (FunctionCollectorVisitor.isNonDeterministic(ex)) {
+ return true;
}
if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ex).isEmpty()) {
return true;
Modified: trunk/engine/src/main/java/org/teiid/query/sql/util/VariableContext.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/util/VariableContext.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/main/java/org/teiid/query/sql/util/VariableContext.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -22,7 +22,9 @@
package org.teiid.query.sql.util;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.teiid.core.TeiidComponentException;
@@ -33,7 +35,7 @@
public class VariableContext {
// map between variables and their values
- private Map variableMap = new HashMap();
+ private Map variableMap = new LinkedHashMap();
// reference to the parent variable context
private VariableContext parentContext;
@@ -48,7 +50,6 @@
public VariableContext(boolean delegateSets) {
this.delegateSets = delegateSets;
- this.variableMap = new HashMap();
}
public void setGlobalValue(String variable, Object value) {
@@ -185,4 +186,8 @@
this.variableMap.putAll(other.variableMap);
}
+ public List<Object> getLocalValues() {
+ return new ArrayList<Object>(this.variableMap.values());
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/FunctionCollectorVisitor.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -26,6 +26,7 @@
import java.util.Collection;
import java.util.HashSet;
+import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.query.QueryPlugin;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
@@ -141,4 +142,15 @@
getFunctions(obj, functions, deep);
return functions;
}
+
+ public static boolean isNonDeterministic(LanguageObject ex) {
+ Collection<Function> functions = FunctionCollectorVisitor.getFunctions(ex, true, false);
+ for (Function function : functions) {
+ if ( function.getFunctionDescriptor().getDeterministic() == Determinism.NONDETERMINISTIC) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-03-19 01:18:44 UTC (rev 3009)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-03-19 14:32:44 UTC (rev 3010)
@@ -7540,6 +7540,30 @@
helpProcess(plan, hdm, expected);
}
+ @Test public void testNonDeterministicScalarSubquery() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
+
+ BasicSourceCapabilities caps = getTypicalCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_SUBQUERIES_SCALAR, false);
+ caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
+ caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, true);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = helpPlan("select count(distinct x) from (select (select uuid()) as x from pm1.g1) as v", metadata, //$NON-NLS-1
+ null, capFinder,
+ new String[] { "SELECT 1 FROM pm1.g1 AS g_0" }, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+
+ HardcodedDataManager hdm = new HardcodedDataManager();
+ hdm.addData("SELECT 1 FROM pm1.g1 AS g_0", new List[] {Arrays.asList(1), Arrays.asList(1)});
+ hdm.setBlockOnce(true);
+ List[] expected = new List[] {
+ Arrays.asList(2),
+ };
+
+ helpProcess(plan, hdm, expected);
+ }
+
@Test public void testUncorrelatedScalarSubqueryPushdown1() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
More information about the teiid-commits
mailing list