Author: shawkins
Date: 2010-10-04 17:04:24 -0400 (Mon, 04 Oct 2010)
New Revision: 2625
Added:
trunk/api/src/main/java/org/teiid/language/With.java
trunk/api/src/main/java/org/teiid/language/WithItem.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/WithQueryCommand.java
trunk/engine/src/test/java/org/teiid/query/processor/TestWithClauseProcessing.java
Removed:
trunk/engine/src/main/java/org/teiid/query/execution/
Modified:
trunk/api/src/main/java/org/teiid/language/QueryExpression.java
trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/DelegatingHierarchyVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java
trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml
trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java
trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java
trunk/engine/src/main/java/org/teiid/query/processor/BatchIterator.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/JoinStrategy.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/PartitionedSortJoin.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/SetQueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageObject.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/Insert.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/QueryCommand.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/SetQuery.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/SubqueryContainer.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ValueIteratorProviderCollectorVisitor.java
trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
Log:
TEIID-1288 TEIID-1171 adding support for explicit table syntax and for non-recursive
common table expressions.
Modified: trunk/api/src/main/java/org/teiid/language/QueryExpression.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/QueryExpression.java 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/api/src/main/java/org/teiid/language/QueryExpression.java 2010-10-04 21:04:24
UTC (rev 2625)
@@ -28,6 +28,7 @@
private OrderBy orderBy;
private Limit limit;
+ private With with;
public abstract Select getProjectedQuery();
@@ -93,4 +94,12 @@
public void setLimit(Limit limit) {
this.limit = limit;
}
+
+ public With getWith() {
+ return with;
+ }
+
+ public void setWith(With with) {
+ this.with = with;
+ }
}
Added: trunk/api/src/main/java/org/teiid/language/With.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/With.java (rev 0)
+++ trunk/api/src/main/java/org/teiid/language/With.java 2010-10-04 21:04:24 UTC (rev
2625)
@@ -0,0 +1,46 @@
+/*
+ * 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.language;
+
+import java.util.List;
+
+import org.teiid.language.visitor.LanguageObjectVisitor;
+
+public class With extends BaseLanguageObject {
+
+ private List<WithItem> items;
+
+ public List<WithItem> getItems() {
+ return items;
+ }
+
+ public void setItems(List<WithItem> items) {
+ this.items = items;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageObjectVisitor visitor) {
+ visitor.visit(this);
+ }
+
+}
Property changes on: trunk/api/src/main/java/org/teiid/language/With.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/api/src/main/java/org/teiid/language/WithItem.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/WithItem.java (rev
0)
+++ trunk/api/src/main/java/org/teiid/language/WithItem.java 2010-10-04 21:04:24 UTC (rev
2625)
@@ -0,0 +1,66 @@
+/*
+ * 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.language;
+
+import java.util.List;
+
+import org.teiid.language.visitor.LanguageObjectVisitor;
+
+public class WithItem extends BaseLanguageObject implements SubqueryContainer {
+
+ private NamedTable table;
+ private List<ColumnReference> columns;
+ private QueryExpression queryExpression;
+
+ public NamedTable getTable() {
+ return table;
+ }
+
+ public void setTable(NamedTable table) {
+ this.table = table;
+ }
+
+ public List<ColumnReference> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List<ColumnReference> columns) {
+ this.columns = columns;
+ }
+
+ @Override
+ public QueryExpression getSubquery() {
+ return queryExpression;
+ }
+
+ @Override
+ public void setSubquery(QueryExpression query) {
+ this.queryExpression = query;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageObjectVisitor visitor) {
+ visitor.visit(this);
+ }
+
+}
Property changes on: trunk/api/src/main/java/org/teiid/language/WithItem.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -63,6 +63,8 @@
import org.teiid.language.SubqueryComparison;
import org.teiid.language.SubqueryIn;
import org.teiid.language.Update;
+import org.teiid.language.With;
+import org.teiid.language.WithItem;
/**
@@ -232,6 +234,16 @@
public void visit(IteratorValueSource obj) {
checkInstance(obj);
}
+
+ @Override
+ public void visit(With obj) {
+ checkInstance(obj);
+ }
+
+ @Override
+ public void visit(WithItem obj) {
+ checkInstance(obj);
+ }
/**
* This is a utility method to instantiate and run the visitor in conjunction
@@ -244,7 +256,7 @@
public static <T> Collection<T> collectObjects(Class<T> type,
LanguageObject object) {
CollectorVisitor<T> visitor = new CollectorVisitor<T>(type);
DelegatingHierarchyVisitor hierarchyVisitor = new
DelegatingHierarchyVisitor(visitor, null);
- object.acceptVisitor(hierarchyVisitor);
+ hierarchyVisitor.visitNode(object);
return visitor.getCollectedObjects();
}
Modified:
trunk/api/src/main/java/org/teiid/language/visitor/DelegatingHierarchyVisitor.java
===================================================================
---
trunk/api/src/main/java/org/teiid/language/visitor/DelegatingHierarchyVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/api/src/main/java/org/teiid/language/visitor/DelegatingHierarchyVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -23,40 +23,7 @@
package org.teiid.language.visitor;
import org.teiid.connector.DataPlugin;
-import org.teiid.language.AggregateFunction;
-import org.teiid.language.AndOr;
-import org.teiid.language.Argument;
-import org.teiid.language.BatchedUpdates;
-import org.teiid.language.Call;
-import org.teiid.language.ColumnReference;
-import org.teiid.language.Comparison;
-import org.teiid.language.Delete;
-import org.teiid.language.DerivedColumn;
-import org.teiid.language.DerivedTable;
-import org.teiid.language.Exists;
-import org.teiid.language.Function;
-import org.teiid.language.GroupBy;
-import org.teiid.language.In;
-import org.teiid.language.Insert;
-import org.teiid.language.IsNull;
-import org.teiid.language.Join;
import org.teiid.language.LanguageObject;
-import org.teiid.language.Like;
-import org.teiid.language.Limit;
-import org.teiid.language.Literal;
-import org.teiid.language.NamedTable;
-import org.teiid.language.Not;
-import org.teiid.language.OrderBy;
-import org.teiid.language.ScalarSubquery;
-import org.teiid.language.SearchedCase;
-import org.teiid.language.SearchedWhenClause;
-import org.teiid.language.Select;
-import org.teiid.language.SetClause;
-import org.teiid.language.SetQuery;
-import org.teiid.language.SortSpecification;
-import org.teiid.language.SubqueryComparison;
-import org.teiid.language.SubqueryIn;
-import org.teiid.language.Update;
/**
* Delegates pre- and post-processing for each node in the hierarchy to
@@ -84,313 +51,17 @@
return preVisitor;
}
- public void visit(AggregateFunction obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(BatchedUpdates obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(Comparison obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(AndOr obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Delete obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(ColumnReference obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Call obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(Exists obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Function obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(NamedTable obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(GroupBy obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(In obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(DerivedTable obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(Insert obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(IsNull obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Join obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Like obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Limit obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Literal obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Not obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(OrderBy obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(SortSpecification obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Argument obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(Select obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(ScalarSubquery obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(SearchedCase obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(DerivedColumn obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(SubqueryComparison obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
- public void visit(SubqueryIn obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(SetQuery obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- public void visit(Update obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
@Override
- public void visit(SetClause obj) {
- if (preVisitor != null) {
- preVisitor.visit(obj);
- }
- super.visit(obj);
- if (postVisitor != null) {
- postVisitor.visit(obj);
- }
- }
-
- @Override
- public void visit(SearchedWhenClause obj) {
+ public void visitNode(LanguageObject obj) {
+ if (obj == null) {
+ return;
+ }
if (preVisitor != null) {
- preVisitor.visit(obj);
+ obj.acceptVisitor(preVisitor);
}
- super.visit(obj);
+ super.visitNode(obj);
if (postVisitor != null) {
- postVisitor.visit(obj);
+ obj.acceptVisitor(postVisitor);
}
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -51,6 +51,8 @@
import org.teiid.language.SubqueryComparison;
import org.teiid.language.SubqueryIn;
import org.teiid.language.Update;
+import org.teiid.language.With;
+import org.teiid.language.WithItem;
/**
* Visits each node in a hierarchy of ILanguageObjects. The default
@@ -158,6 +160,7 @@
}
public void visit(Select obj) {
+ visitNode(obj.getWith());
visitNodes(obj.getDerivedColumns());
visitNodes(obj.getFrom());
visitNode(obj.getWhere());
@@ -203,6 +206,7 @@
}
public void visit(SetQuery obj) {
+ visitNode(obj.getWith());
if (visitSubcommands) {
visitNode(obj.getLeftQuery());
visitNode(obj.getRightQuery());
@@ -229,5 +233,20 @@
visitNode(obj.getSymbol());
visitNode(obj.getValue());
}
+
+ @Override
+ public void visit(With obj) {
+ visitNodes(obj.getItems());
+ }
+
+ @Override
+ public void visit(WithItem obj) {
+ visitNode(obj.getTable());
+ visitNodes(obj.getColumns());
+ if (visitSubcommands) {
+ visitNode(obj.getSubquery());
+ }
+ }
+
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
===================================================================
---
trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -62,4 +62,6 @@
public void visit(SetClause obj);
public void visit(SearchedWhenClause obj);
public void visit(IteratorValueSource obj);
+ public void visit(With obj);
+ public void visit(WithItem obj);
}
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -71,6 +71,8 @@
import org.teiid.language.SubqueryIn;
import org.teiid.language.TableReference;
import org.teiid.language.Update;
+import org.teiid.language.With;
+import org.teiid.language.WithItem;
import org.teiid.language.Argument.Direction;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.language.SQLConstants.Tokens;
@@ -676,6 +678,9 @@
}
public void visit(Select obj) {
+ if (obj.getWith() != null) {
+ append(obj.getWith());
+ }
buffer.append(SELECT).append(Tokens.SPACE);
buffer.append(getSourceComment(obj));
if (obj.isDistinct()) {
@@ -824,6 +829,9 @@
}
public void visit(SetQuery obj) {
+ if (obj.getWith() != null) {
+ append(obj.getWith());
+ }
appendSetQuery(obj, obj.getLeftQuery(), false);
buffer.append(Tokens.SPACE);
@@ -874,6 +882,29 @@
append(obj);
}
}
+
+ @Override
+ public void visit(With obj) {
+ buffer.append(WITH);
+ buffer.append(Tokens.SPACE);
+ append(obj.getItems());
+ }
+
+ @Override
+ public void visit(WithItem obj) {
+ append(obj.getTable());
+ buffer.append(Tokens.SPACE);
+ if (obj.getColumns() != null) {
+ buffer.append(Tokens.LPAREN);
+ append(obj.getColumns());
+ buffer.append(Tokens.RPAREN);
+ buffer.append(Tokens.SPACE);
+ }
+ buffer.append(AS);
+ buffer.append(Tokens.LPAREN);
+ append(obj.getSubquery());
+ buffer.append(Tokens.RPAREN);
+ }
/**
* Gets the SQL string representation for a given ILanguageObject.
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2010-10-04 21:04:24
UTC (rev 2625)
@@ -785,4 +785,8 @@
public boolean areLobsUsableAfterClose() {
return false;
}
+
+ public boolean supportsCommonTableExpressions() {
+ return false;
+ }
}
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-10-04 19:26:58 UTC (rev
2624)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-10-04 21:04:24 UTC (rev
2625)
@@ -26,6 +26,11 @@
</UL>
<H2><A NAME="Highlights"></A>Highlights</H2>
<UL>
+ <LI><B>SQL Support</B>
+ <UL>
+ <LI><B>Non-Recursive Common Table Expressions</B> - The WITH
clause (and associated pushdown) for non-recursive queries is now supported.
+ <LI><B>Explicit Table Syntax</B> - TABLE x can now be used as a
shortcut for SELECT * FROM x
+ </UL>
<LI><B>Transaction Statements</B> - JDBC/ODBC now accepts START
TRANSACTION, COMMIT, and ROLLBACK statements to control local transactions.
<LI><B>Procedure Result Caching</B> - virtual procedure definitions
may use a cache hint to cache results in the result set cache.
<LI><B>Improved Plan Caching</B> - plans used by internal
materialization and stored procedure plans will be automatically cached in the prepared
plan cache. Improvements were also made to reduce the memory footprint of the plans.
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java
===================================================================
---
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -249,5 +249,10 @@
@Override
public boolean supportsAggregatesEnhancedNumeric() {
return true;
+ }
+
+ @Override
+ public boolean supportsCommonTableExpressions() {
+ return true;
}
}
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
===================================================================
---
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -62,7 +62,7 @@
import org.teiid.translator.jdbc.LocateFunctionModifier;
-@Translator(name="oracle", description="A translator for Oracle
Database")
+@Translator(name="oracle", description="A translator for Oracle 9i
Database or later")
public class OracleExecutionFactory extends JDBCExecutionFactory {
private static final String TIME_FORMAT = "HH24:MI:SS"; //$NON-NLS-1$
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
===================================================================
---
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -462,4 +462,9 @@
return getDatabaseVersion().compareTo(EIGHT_2) >= 0;
}
+ @Override
+ public boolean supportsCommonTableExpressions() {
+ return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
+ }
+
}
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java
===================================================================
---
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sqlserver/SQLServerExecutionFactory.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -204,5 +204,10 @@
public boolean booleanNullable() {
return true;
}
+
+ @Override
+ public boolean supportsCommonTableExpressions() {
+ return true;
+ }
}
Modified:
trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml
===================================================================
---
trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml 2010-10-04
21:04:24 UTC (rev 2625)
@@ -438,7 +438,7 @@
<section>
<title>QueryExpression Structure</title>
<para><code>QueryExpression</code> is the base for both SELECT
queries and set queries. It may optionally take an
- <code>OrderBy</code> (representing a SQL ORDER BY clause) and a
<code>Limit</code> (represent a SQL LIMIT clause)</para>
+ <code>OrderBy</code> (representing a SQL ORDER BY clause), a
<code>Limit</code> (represent a SQL LIMIT clause), or a
<code>With</code> (represents a SQL WITH clause).</para>
</section>
<section>
@@ -459,6 +459,14 @@
INTERSECT, EXCEPT) on two <code>QueryExpression</code>. The all flag may
be set to
indicate UNION ALL (currently INTERSECT and EXCEPT ALL are not allowed in
Teiid)</para>
</section>
+
+ <section>
+ <title>With Structure</title>
+
+ <para>A <code>With</code> clause contains named
<code>QueryExpressions</code> held by <code>WithItem</code>s that
can be
+ referenced as tables in the main
<code>QueryExpression</code>.</para>
+
+ </section>
<section>
<title>Insert Structure</title>
@@ -1265,6 +1273,17 @@
<para>Translator supports inserts with an iterator of values.
The values would typically be from an evaluated QueryExpression.</para>
</entry>
</row>
+ <row>
+ <entry>
+ <para>CommonTableExpressions</para>
+ </entry>
+ <entry>
+ <para/>
+ </entry>
+ <entry>
+ <para>Translator supports the WITH clause.</para>
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2010-10-04
21:04:24 UTC (rev 2625)
@@ -503,7 +503,7 @@
<row>
<entry align="right" valign="top"><para><anchor
id="prod8"
xreflabel="storedProcedure"/>storedProcedure</para></entry>
<entry align="left" valign="top"><para>::=
-( ( ( <EXEC> ) | ( <EXECUTE> ) | ( <CALL> ) )
<link linkend="prod2">id</link> <LPAREN> ( <link
linkend="prod39">executeNamedParams</link> | <link
linkend="prod37">executeUnnamedParams</link> ) <RPAREN> )
( <link linkend="prod38">option</link>
)?</para></entry></row>
+( ( <EXEC> | <EXECUTE> | <CALL> ) <link
linkend="prod2">id</link> <LPAREN> ( <link
linkend="prod39">executeNamedParams</link> | <link
linkend="prod37">executeUnnamedParams</link> ) <RPAREN> )
( <link linkend="prod38">option</link>
)?</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor
id="prod37"
xreflabel="executeUnnamedParams"/>executeUnnamedParams</para></entry>
<entry align="left" valign="top"><para>::=
@@ -515,97 +515,105 @@
<row>
<entry align="right" valign="top"><para><anchor
id="prod9" xreflabel="insert"/>insert</para></entry>
<entry align="left" valign="top"><para>::=
-<INSERT> <INTO> <link
linkend="prod2">id</link> ( <LPAREN> <link
linkend="prod2">id</link> ( <COMMA> <link
linkend="prod2">id</link> )* <RPAREN> )? ( (
<VALUES> <link linkend="prod40">rowValues</link> ) | (
<link linkend="prod7">queryExpression</link> ) ) ( <link
linkend="prod38">option</link>
)?</para></entry></row>
+<INSERT> <INTO> <link
linkend="prod2">id</link> ( <link
linkend="prod40">columnList</link> )? ( ( <VALUES>
<link linkend="prod41">rowValues</link> ) | ( <link
linkend="prod7">queryExpression</link> ) ) ( <link
linkend="prod38">option</link>
)?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod40"
xreflabel="rowValues"/>rowValues</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod40"
xreflabel="columnList"/>columnList</para></entry>
<entry align="left" valign="top"><para>::=
+<LPAREN> <link linkend="prod2">id</link> (
<COMMA> <link linkend="prod2">id</link> )*
<RPAREN></para></entry></row>
+<row>
+<entry align="right" valign="top"><para><anchor
id="prod41"
xreflabel="rowValues"/>rowValues</para></entry>
+<entry align="left" valign="top"><para>::=
<LPAREN> <link linkend="prod17">expression</link> (
<COMMA> <link linkend="prod17">expression</link> )*
<RPAREN></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor
id="prod10" xreflabel="update"/>update</para></entry>
<entry align="left" valign="top"><para>::=
-<UPDATE> <link linkend="prod2">id</link>
<SET> <link linkend="prod36">setClauseList</link> (
<link linkend="prod41">where</link> )? ( <link
linkend="prod38">option</link>
)?</para></entry></row>
+<UPDATE> <link linkend="prod2">id</link>
<SET> <link linkend="prod36">setClauseList</link> (
<link linkend="prod42">where</link> )? ( <link
linkend="prod38">option</link>
)?</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor
id="prod11" xreflabel="delete"/>delete</para></entry>
<entry align="left" valign="top"><para>::=
-<DELETE> <FROM> <link
linkend="prod2">id</link> ( <link
linkend="prod41">where</link> )? ( <link
linkend="prod38">option</link>
)?</para></entry></row>
+<DELETE> <FROM> <link
linkend="prod2">id</link> ( <link
linkend="prod42">where</link> )? ( <link
linkend="prod38">option</link>
)?</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor
id="prod7"
xreflabel="queryExpression"/>queryExpression</para></entry>
<entry align="left" valign="top"><para>::=
-<link
linkend="prod42">queryExpressionBody</link></para></entry></row>
+( <WITH> <link
linkend="prod43">withListElement</link> ( <COMMA>
<link linkend="prod43">withListElement</link> )* )? <link
linkend="prod44">queryExpressionBody</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod42"
xreflabel="queryExpressionBody"/>queryExpressionBody</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod43"
xreflabel="withListElement"/>withListElement</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod43">queryTerm</link> ( ( <UNION> |
<EXCEPT> ) ( <ALL> | <DISTINCT> )? <link
linkend="prod43">queryTerm</link> )* ( <link
linkend="prod44">orderby</link> )? ( <link
linkend="prod45">limit</link> )? ( <link
linkend="prod38">option</link>
)?</para></entry></row>
+<link linkend="prod2">id</link> ( <link
linkend="prod40">columnList</link> )? <AS>
<LPAREN> <link linkend="prod7">queryExpression</link>
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod43"
xreflabel="queryTerm"/>queryTerm</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod44"
xreflabel="queryExpressionBody"/>queryExpressionBody</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod46">queryPrimary</link> (
<INTERSECT> ( <ALL> | <DISTINCT> )? <link
linkend="prod46">queryPrimary</link>
)*</para></entry></row>
+<link linkend="prod45">queryTerm</link> ( ( <UNION> |
<EXCEPT> ) ( <ALL> | <DISTINCT> )? <link
linkend="prod45">queryTerm</link> )* ( <link
linkend="prod46">orderby</link> )? ( <link
linkend="prod47">limit</link> )? ( <link
linkend="prod38">option</link>
)?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod46"
xreflabel="queryPrimary"/>queryPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod45"
xreflabel="queryTerm"/>queryTerm</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod47">query</link> | ( <LPAREN>
<link linkend="prod42">queryExpressionBody</link>
<RPAREN> ) )</para></entry></row>
+<link linkend="prod48">queryPrimary</link> (
<INTERSECT> ( <ALL> | <DISTINCT> )? <link
linkend="prod48">queryPrimary</link>
)*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod47" xreflabel="query"/>query</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod48"
xreflabel="queryPrimary"/>queryPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod48">select</link> ( <link
linkend="prod49">into</link> )? ( <link
linkend="prod50">from</link> ( <link
linkend="prod41">where</link> )? ( <link
linkend="prod51">groupBy</link> )? ( <link
linkend="prod52">having</link> )?
)?</para></entry></row>
+( <link linkend="prod49">query</link> | ( <TABLE>
<link linkend="prod2">id</link> ) | ( <LPAREN>
<link linkend="prod44">queryExpressionBody</link>
<RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod49" xreflabel="into"/>into</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod49" xreflabel="query"/>query</para></entry>
<entry align="left" valign="top"><para>::=
+<link linkend="prod50">select</link> ( <link
linkend="prod51">into</link> )? ( <link
linkend="prod52">from</link> ( <link
linkend="prod42">where</link> )? ( <link
linkend="prod53">groupBy</link> )? ( <link
linkend="prod54">having</link> )?
)?</para></entry></row>
+<row>
+<entry align="right" valign="top"><para><anchor
id="prod51" xreflabel="into"/>into</para></entry>
+<entry align="left" valign="top"><para>::=
<INTO> ( <link linkend="prod2">id</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod48" xreflabel="select"/>select</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod50" xreflabel="select"/>select</para></entry>
<entry align="left" valign="top"><para>::=
-<SELECT> ( <ALL> | ( <DISTINCT> ) )? (
<STAR> | ( <link linkend="prod53">selectSymbol</link>
( <COMMA> <link linkend="prod53">selectSymbol</link>
)* ) )</para></entry></row>
+<SELECT> ( <ALL> | ( <DISTINCT> ) )? (
<STAR> | ( <link linkend="prod55">selectSymbol</link>
( <COMMA> <link linkend="prod55">selectSymbol</link>
)* ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod53"
xreflabel="selectSymbol"/>selectSymbol</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod55"
xreflabel="selectSymbol"/>selectSymbol</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod54">selectExpression</link> | <link
linkend="prod55">allInGroupSymbol</link>
)</para></entry></row>
+( <link linkend="prod56">selectExpression</link> | <link
linkend="prod57">allInGroupSymbol</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod54"
xreflabel="selectExpression"/>selectExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod56"
xreflabel="selectExpression"/>selectExpression</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod17">expression</link> ( ( <AS>
)? <link linkend="prod2">id</link> )?
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod56"
xreflabel="derivedColumn"/>derivedColumn</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod58"
xreflabel="derivedColumn"/>derivedColumn</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod17">expression</link> ( <AS>
<link linkend="prod2">id</link> )?
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod55"
xreflabel="allInGroupSymbol"/>allInGroupSymbol</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod57"
xreflabel="allInGroupSymbol"/>allInGroupSymbol</para></entry>
<entry align="left" valign="top"><para>::=
<ALL_IN_GROUP></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod57" xreflabel="xmlAgg"/>xmlAgg</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod59" xreflabel="xmlAgg"/>xmlAgg</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLAGG> <LPAREN> <link
linkend="prod17">expression</link> ( <link
linkend="prod44">orderby</link> )?
<RPAREN></para></entry></row>
+<XMLAGG> <LPAREN> <link
linkend="prod17">expression</link> ( <link
linkend="prod46">orderby</link> )?
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod58"
xreflabel="aggregateSymbol"/>aggregateSymbol</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod60"
xreflabel="aggregateSymbol"/>aggregateSymbol</para></entry>
<entry align="left" valign="top"><para>::=
( ( <link linkend="prod15">nonReserved</link>
<LPAREN> <STAR> <RPAREN> ) | ( ( <link
linkend="prod15">nonReserved</link> | <ANY> |
<SOME> ) <LPAREN> ( <DISTINCT> |
<ALL> )? <link linkend="prod17">expression</link>
<RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod50" xreflabel="from"/>from</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod52" xreflabel="from"/>from</para></entry>
<entry align="left" valign="top"><para>::=
-<FROM> ( <link linkend="prod59">tableReference</link>
( <COMMA> <link linkend="prod59">tableReference</link>
)* )</para></entry></row>
+<FROM> ( <link linkend="prod61">tableReference</link>
( <COMMA> <link linkend="prod61">tableReference</link>
)* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod59"
xreflabel="tableReference"/>tableReference</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod61"
xreflabel="tableReference"/>tableReference</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <LBRACE> <link
linkend="prod15">nonReserved</link> <link
linkend="prod60">joinedTable</link> <RBRACE> ) | <link
linkend="prod60">joinedTable</link>
)</para></entry></row>
+( ( <LBRACE> <link
linkend="prod15">nonReserved</link> <link
linkend="prod62">joinedTable</link> <RBRACE> ) | <link
linkend="prod62">joinedTable</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod60"
xreflabel="joinedTable"/>joinedTable</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod62"
xreflabel="joinedTable"/>joinedTable</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod61">tablePrimary</link> ( ( <link
linkend="prod62">crossJoin</link> | <link
linkend="prod63">qualifiedJoin</link> )
)*</para></entry></row>
+<link linkend="prod63">tablePrimary</link> ( ( <link
linkend="prod64">crossJoin</link> | <link
linkend="prod65">qualifiedJoin</link> )
)*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod62"
xreflabel="crossJoin"/>crossJoin</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod64"
xreflabel="crossJoin"/>crossJoin</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <CROSS> | <UNION> ) <JOIN> <link
linkend="prod61">tablePrimary</link>
)</para></entry></row>
+( ( <CROSS> | <UNION> ) <JOIN> <link
linkend="prod63">tablePrimary</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod63"
xreflabel="qualifiedJoin"/>qualifiedJoin</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod65"
xreflabel="qualifiedJoin"/>qualifiedJoin</para></entry>
<entry align="left" valign="top"><para>::=
-( ( ( <RIGHT> ( <OUTER> )? ) | ( <LEFT> (
<OUTER> )? ) | ( <FULL> ( <OUTER> )? ) |
<INNER> )? <JOIN> <link
linkend="prod59">tableReference</link> <ON> <link
linkend="prod29">criteria</link>
)</para></entry></row>
+( ( ( <RIGHT> ( <OUTER> )? ) | ( <LEFT> (
<OUTER> )? ) | ( <FULL> ( <OUTER> )? ) |
<INNER> )? <JOIN> <link
linkend="prod61">tableReference</link> <ON> <link
linkend="prod29">criteria</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod61"
xreflabel="tablePrimary"/>tablePrimary</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod63"
xreflabel="tablePrimary"/>tablePrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod64">textTable</link> | <link
linkend="prod65">xmlTable</link> | <link
linkend="prod66">unaryFromClause</link> | <link
linkend="prod67">subqueryFromClause</link> | ( <LPAREN>
<link linkend="prod60">joinedTable</link> <RPAREN> ) )
( ( <MAKEDEP> ) | ( <MAKENOTDEP> )
)?</para></entry></row>
+( <link linkend="prod66">textTable</link> | <link
linkend="prod67">xmlTable</link> | <link
linkend="prod68">unaryFromClause</link> | <link
linkend="prod69">subqueryFromClause</link> | ( <LPAREN>
<link linkend="prod62">joinedTable</link> <RPAREN> ) )
( ( <MAKEDEP> ) | ( <MAKENOTDEP> )
)?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod68"
xreflabel="xmlSerialize"/>xmlSerialize</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod70"
xreflabel="xmlSerialize"/>xmlSerialize</para></entry>
<entry align="left" valign="top"><para>::=
<XMLSERIALIZE> <LPAREN> ( <link
linkend="prod15">nonReserved</link> )? <link
linkend="prod17">expression</link> ( <AS> (
<STRING> | <VARCHAR> | <CLOB> ) )?
<RPAREN></para></entry></row>
<row>
@@ -613,127 +621,127 @@
<entry align="left" valign="top"><para>::=
<ID></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod64"
xreflabel="textTable"/>textTable</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod66"
xreflabel="textTable"/>textTable</para></entry>
<entry align="left" valign="top"><para>::=
-<ID> <LPAREN> <link
linkend="prod17">expression</link> <link
linkend="prod15">nonReserved</link> <link
linkend="prod69">textColumn</link> ( <COMMA> <link
linkend="prod69">textColumn</link> )* ( <ID> <link
linkend="prod70">charVal</link> )? ( ( <ESCAPE> <link
linkend="prod70">charVal</link> ) | ( <ID> <link
linkend="prod70">charVal</link> ) )? ( <ID> ( <link
linkend="prod71">intVal</link> )? )? ( <ID> <link
linkend="prod71">intVal</link> )? <RPAREN> (
<AS> )? <link
linkend="prod2">id</link></para></entry></row>
+<ID> <LPAREN> <link
linkend="prod17">expression</link> <link
linkend="prod15">nonReserved</link> <link
linkend="prod71">textColumn</link> ( <COMMA> <link
linkend="prod71">textColumn</link> )* ( <ID> <link
linkend="prod72">charVal</link> )? ( ( <ESCAPE> <link
linkend="prod72">charVal</link> ) | ( <ID> <link
linkend="prod72">charVal</link> ) )? ( <ID> ( <link
linkend="prod73">intVal</link> )? )? ( <ID> <link
linkend="prod73">intVal</link> )? <RPAREN> (
<AS> )? <link
linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod69"
xreflabel="textColumn"/>textColumn</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod71"
xreflabel="textColumn"/>textColumn</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod2">id</link> <link
linkend="prod32">dataType</link> ( <ID> <link
linkend="prod71">intVal</link>
)?</para></entry></row>
+<link linkend="prod2">id</link> <link
linkend="prod32">dataType</link> ( <ID> <link
linkend="prod73">intVal</link>
)?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod72"
xreflabel="xmlQuery"/>xmlQuery</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod74"
xreflabel="xmlQuery"/>xmlQuery</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLQUERY> <LPAREN> ( <link
linkend="prod73">xmlNamespaces</link> <COMMA> )? <link
linkend="prod1">stringVal</link> ( <ID> <link
linkend="prod56">derivedColumn</link> ( <COMMA> <link
linkend="prod56">derivedColumn</link> )* )? ( ( <NULL> |
<link linkend="prod15">nonReserved</link> ) <ON>
<link linkend="prod15">nonReserved</link> )?
<RPAREN></para></entry></row>
+<XMLQUERY> <LPAREN> ( <link
linkend="prod75">xmlNamespaces</link> <COMMA> )? <link
linkend="prod1">stringVal</link> ( <ID> <link
linkend="prod58">derivedColumn</link> ( <COMMA> <link
linkend="prod58">derivedColumn</link> )* )? ( ( <NULL> |
<link linkend="prod15">nonReserved</link> ) <ON>
<link linkend="prod15">nonReserved</link> )?
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod65"
xreflabel="xmlTable"/>xmlTable</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod67"
xreflabel="xmlTable"/>xmlTable</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLTABLE> <LPAREN> ( <link
linkend="prod73">xmlNamespaces</link> <COMMA> )? <link
linkend="prod1">stringVal</link> ( <ID> <link
linkend="prod56">derivedColumn</link> ( <COMMA> <link
linkend="prod56">derivedColumn</link> )* )? ( <ID>
<link linkend="prod74">xmlColumn</link> ( <COMMA>
<link linkend="prod74">xmlColumn</link> )* )? <RPAREN>
( <AS> )? <link
linkend="prod2">id</link></para></entry></row>
+<XMLTABLE> <LPAREN> ( <link
linkend="prod75">xmlNamespaces</link> <COMMA> )? <link
linkend="prod1">stringVal</link> ( <ID> <link
linkend="prod58">derivedColumn</link> ( <COMMA> <link
linkend="prod58">derivedColumn</link> )* )? ( <ID>
<link linkend="prod76">xmlColumn</link> ( <COMMA>
<link linkend="prod76">xmlColumn</link> )* )? <RPAREN>
( <AS> )? <link
linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod74"
xreflabel="xmlColumn"/>xmlColumn</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod76"
xreflabel="xmlColumn"/>xmlColumn</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod2">id</link> ( ( <FOR> <link
linkend="prod15">nonReserved</link> ) | ( <link
linkend="prod32">dataType</link> ( <DEFAULT_KEYWORD>
<link linkend="prod17">expression</link> )? ( <link
linkend="prod15">nonReserved</link> <link
linkend="prod1">stringVal</link> )? )
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod71" xreflabel="intVal"/>intVal</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod73" xreflabel="intVal"/>intVal</para></entry>
<entry align="left" valign="top"><para>::=
<INTEGERVAL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod67"
xreflabel="subqueryFromClause"/>subqueryFromClause</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod69"
xreflabel="subqueryFromClause"/>subqueryFromClause</para></entry>
<entry align="left" valign="top"><para>::=
( <TABLE> )? <LPAREN> ( <link
linkend="prod7">queryExpression</link> | <link
linkend="prod8">storedProcedure</link> ) <RPAREN> (
<AS> )? <link
linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod66"
xreflabel="unaryFromClause"/>unaryFromClause</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod68"
xreflabel="unaryFromClause"/>unaryFromClause</para></entry>
<entry align="left" valign="top"><para>::=
( <ID> ( ( <AS> )? <link
linkend="prod2">id</link> )? )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod41" xreflabel="where"/>where</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod42" xreflabel="where"/>where</para></entry>
<entry align="left" valign="top"><para>::=
<WHERE> <link
linkend="prod29">criteria</link></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor
id="prod29"
xreflabel="criteria"/>criteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link
linkend="prod75">compoundCritOr</link></para></entry></row>
+<link
linkend="prod77">compoundCritOr</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod75"
xreflabel="compoundCritOr"/>compoundCritOr</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod77"
xreflabel="compoundCritOr"/>compoundCritOr</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod76">compoundCritAnd</link> ( <OR>
<link linkend="prod76">compoundCritAnd</link>
)*</para></entry></row>
+<link linkend="prod78">compoundCritAnd</link> ( <OR>
<link linkend="prod78">compoundCritAnd</link>
)*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod76"
xreflabel="compoundCritAnd"/>compoundCritAnd</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod78"
xreflabel="compoundCritAnd"/>compoundCritAnd</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod77">notCrit</link> ( <AND>
<link linkend="prod77">notCrit</link>
)*</para></entry></row>
+<link linkend="prod79">notCrit</link> ( <AND>
<link linkend="prod79">notCrit</link>
)*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod77"
xreflabel="notCrit"/>notCrit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod79"
xreflabel="notCrit"/>notCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <link
linkend="prod78">booleanPrimary</link></para></entry></row>
+( <NOT> )? <link
linkend="prod80">booleanPrimary</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod78"
xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod80"
xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod35">translateCriteria</link> | ( <link
linkend="prod79">commonValueExpression</link> ( ( <link
linkend="prod80">betweenCrit</link> | <link
linkend="prod81">matchCrit</link> | <link
linkend="prod82">setCrit</link> | <link
linkend="prod83">isNullCrit</link> | <link
linkend="prod84">subqueryCompareCriteria</link> | <link
linkend="prod85">compareCrit</link> ) )? ) | <link
linkend="prod86">existsCriteria</link> | <link
linkend="prod31">hasCriteria</link>
)</para></entry></row>
+( <link linkend="prod35">translateCriteria</link> | ( <link
linkend="prod81">commonValueExpression</link> ( ( <link
linkend="prod82">betweenCrit</link> | <link
linkend="prod83">matchCrit</link> | <link
linkend="prod84">setCrit</link> | <link
linkend="prod85">isNullCrit</link> | <link
linkend="prod86">subqueryCompareCriteria</link> | <link
linkend="prod87">compareCrit</link> ) )? ) | <link
linkend="prod88">existsCriteria</link> | <link
linkend="prod31">hasCriteria</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod87"
xreflabel="operator"/>operator</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod89"
xreflabel="operator"/>operator</para></entry>
<entry align="left" valign="top"><para>::=
( <EQ> | <NE> | <NE2> | <LT> |
<LE> | <GT> | <GE>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod85"
xreflabel="compareCrit"/>compareCrit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod87"
xreflabel="compareCrit"/>compareCrit</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod87">operator</link> <link
linkend="prod79">commonValueExpression</link></para></entry></row>
+<link linkend="prod89">operator</link> <link
linkend="prod81">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod88"
xreflabel="subquery"/>subquery</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod90"
xreflabel="subquery"/>subquery</para></entry>
<entry align="left" valign="top"><para>::=
<LPAREN> ( <link
linkend="prod7">queryExpression</link> | <link
linkend="prod8">storedProcedure</link> )
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod84"
xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod86"
xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod87">operator</link> ( <ANY> |
<SOME> | <ALL> ) <link
linkend="prod88">subquery</link></para></entry></row>
+<link linkend="prod89">operator</link> ( <ANY> |
<SOME> | <ALL> ) <link
linkend="prod90">subquery</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod81"
xreflabel="matchCrit"/>matchCrit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod83"
xreflabel="matchCrit"/>matchCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <LIKE> <link
linkend="prod79">commonValueExpression</link> ( <ESCAPE>
<link linkend="prod70">charVal</link> | ( <LBRACE>
<ESCAPE> <link linkend="prod70">charVal</link>
<RBRACE> ) )?</para></entry></row>
+( <NOT> )? <LIKE> <link
linkend="prod81">commonValueExpression</link> ( <ESCAPE>
<link linkend="prod72">charVal</link> | ( <LBRACE>
<ESCAPE> <link linkend="prod72">charVal</link>
<RBRACE> ) )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod70"
xreflabel="charVal"/>charVal</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod72"
xreflabel="charVal"/>charVal</para></entry>
<entry align="left" valign="top"><para>::=
<link
linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod80"
xreflabel="betweenCrit"/>betweenCrit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod82"
xreflabel="betweenCrit"/>betweenCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <BETWEEN> <link
linkend="prod79">commonValueExpression</link> <AND>
<link
linkend="prod79">commonValueExpression</link></para></entry></row>
+( <NOT> )? <BETWEEN> <link
linkend="prod81">commonValueExpression</link> <AND>
<link
linkend="prod81">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod83"
xreflabel="isNullCrit"/>isNullCrit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod85"
xreflabel="isNullCrit"/>isNullCrit</para></entry>
<entry align="left" valign="top"><para>::=
<IS> ( <NOT> )?
<NULL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod82"
xreflabel="setCrit"/>setCrit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod84"
xreflabel="setCrit"/>setCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <IN> ( ( <link
linkend="prod88">subquery</link> ) | ( <LPAREN> <link
linkend="prod79">commonValueExpression</link> ( <COMMA>
<link linkend="prod79">commonValueExpression</link> )*
<RPAREN> ) )</para></entry></row>
+( <NOT> )? <IN> ( ( <link
linkend="prod90">subquery</link> ) | ( <LPAREN> <link
linkend="prod81">commonValueExpression</link> ( <COMMA>
<link linkend="prod81">commonValueExpression</link> )*
<RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod86"
xreflabel="existsCriteria"/>existsCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod88"
xreflabel="existsCriteria"/>existsCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<EXISTS> <link
linkend="prod88">subquery</link></para></entry></row>
+<EXISTS> <link
linkend="prod90">subquery</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod51"
xreflabel="groupBy"/>groupBy</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod53"
xreflabel="groupBy"/>groupBy</para></entry>
<entry align="left" valign="top"><para>::=
-<GROUP> <BY> ( <link
linkend="prod89">groupByItem</link> ( <COMMA> <link
linkend="prod89">groupByItem</link> )*
)</para></entry></row>
+<GROUP> <BY> ( <link
linkend="prod91">groupByItem</link> ( <COMMA> <link
linkend="prod91">groupByItem</link> )*
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod89"
xreflabel="groupByItem"/>groupByItem</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod91"
xreflabel="groupByItem"/>groupByItem</para></entry>
<entry align="left" valign="top"><para>::=
<link
linkend="prod17">expression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod52" xreflabel="having"/>having</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod54" xreflabel="having"/>having</para></entry>
<entry align="left" valign="top"><para>::=
<HAVING> <link
linkend="prod29">criteria</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod44"
xreflabel="orderby"/>orderby</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod46"
xreflabel="orderby"/>orderby</para></entry>
<entry align="left" valign="top"><para>::=
-<ORDER> <BY> <link
linkend="prod90">sortSpecification</link> ( <COMMA>
<link linkend="prod90">sortSpecification</link>
)*</para></entry></row>
+<ORDER> <BY> <link
linkend="prod92">sortSpecification</link> ( <COMMA>
<link linkend="prod92">sortSpecification</link>
)*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod90"
xreflabel="sortSpecification"/>sortSpecification</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod92"
xreflabel="sortSpecification"/>sortSpecification</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod91">sortKey</link> ( <ASC> |
<DESC> )? ( <link linkend="prod15">nonReserved</link>
<link linkend="prod15">nonReserved</link>
)?</para></entry></row>
+<link linkend="prod93">sortKey</link> ( <ASC> |
<DESC> )? ( <link linkend="prod15">nonReserved</link>
<link linkend="prod15">nonReserved</link>
)?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod91"
xreflabel="sortKey"/>sortKey</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod93"
xreflabel="sortKey"/>sortKey</para></entry>
<entry align="left" valign="top"><para>::=
<link
linkend="prod17">expression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod45" xreflabel="limit"/>limit</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod47" xreflabel="limit"/>limit</para></entry>
<entry align="left" valign="top"><para>::=
<LIMIT> ( <INTEGERVAL> | <QMARK> ) (
<COMMA> ( <INTEGERVAL> | <QMARK> )
)?</para></entry></row>
<row>
@@ -745,71 +753,71 @@
<entry align="left" valign="top"><para>::=
<link
linkend="prod29">criteria</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod79"
xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod81"
xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod92">plusExpression</link> (
<CONCAT_OP> <link
linkend="prod92">plusExpression</link> )*
)</para></entry></row>
+( <link linkend="prod94">plusExpression</link> (
<CONCAT_OP> <link
linkend="prod94">plusExpression</link> )*
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod92"
xreflabel="plusExpression"/>plusExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod94"
xreflabel="plusExpression"/>plusExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod93">timesExpression</link> ( <link
linkend="prod94">plusOperator</link> <link
linkend="prod93">timesExpression</link> )*
)</para></entry></row>
+( <link linkend="prod95">timesExpression</link> ( <link
linkend="prod96">plusOperator</link> <link
linkend="prod95">timesExpression</link> )*
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod94"
xreflabel="plusOperator"/>plusOperator</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod96"
xreflabel="plusOperator"/>plusOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <PLUS> | <MINUS> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod93"
xreflabel="timesExpression"/>timesExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod95"
xreflabel="timesExpression"/>timesExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod95">valueExpressionPrimary</link> ( <link
linkend="prod96">timesOperator</link> <link
linkend="prod95">valueExpressionPrimary</link> )*
)</para></entry></row>
+( <link linkend="prod97">valueExpressionPrimary</link> ( <link
linkend="prod98">timesOperator</link> <link
linkend="prod97">valueExpressionPrimary</link> )*
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod96"
xreflabel="timesOperator"/>timesOperator</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod98"
xreflabel="timesOperator"/>timesOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <STAR> | <SLASH> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod95"
xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod97"
xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <QMARK> | <link linkend="prod97">literal</link> | (
<LBRACE> <link linkend="prod15">nonReserved</link>
<link linkend="prod98">function</link> <RBRACE> ) | (
<link linkend="prod58">aggregateSymbol</link> ) | ( <link
linkend="prod58">aggregateSymbol</link> ) | ( <link
linkend="prod58">aggregateSymbol</link> ) | ( <link
linkend="prod57">xmlAgg</link> ) | ( <link
linkend="prod98">function</link> ) | ( <ID> ) | <link
linkend="prod88">subquery</link> | ( <LPAREN> <link
linkend="prod17">expression</link> <RPAREN> ) | <link
linkend="prod99">searchedCaseExpression</link> | <link
linkend="prod100">caseExpression</link>
)</para></entry></row>
+( <QMARK> | <link linkend="prod99">literal</link> | (
<LBRACE> <link linkend="prod15">nonReserved</link>
<link linkend="prod100">function</link> <RBRACE> ) | (
<link linkend="prod60">aggregateSymbol</link> ) | ( <link
linkend="prod60">aggregateSymbol</link> ) | ( <link
linkend="prod60">aggregateSymbol</link> ) | ( <link
linkend="prod59">xmlAgg</link> ) | ( <link
linkend="prod100">function</link> ) | ( <ID> ) | <link
linkend="prod90">subquery</link> | ( <LPAREN> <link
linkend="prod17">expression</link> <RPAREN> ) | <link
linkend="prod101">searchedCaseExpression</link> | <link
linkend="prod102">caseExpression</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod100"
xreflabel="caseExpression"/>caseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod102"
xreflabel="caseExpression"/>caseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> <link linkend="prod17">expression</link> (
<WHEN> <link linkend="prod17">expression</link>
<THEN> <link linkend="prod17">expression</link> )+ (
<ELSE> <link linkend="prod17">expression</link> )?
<END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod99"
xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod101"
xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> ( <WHEN> <link
linkend="prod29">criteria</link> <THEN> <link
linkend="prod17">expression</link> )+ ( <ELSE> <link
linkend="prod17">expression</link> )?
<END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod98"
xreflabel="function"/>function</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod100"
xreflabel="function"/>function</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <CONVERT> <LPAREN> <link
linkend="prod17">expression</link> <COMMA> <link
linkend="prod32">dataType</link> <RPAREN> ) | (
<CAST> <LPAREN> <link
linkend="prod17">expression</link> <AS> <link
linkend="prod32">dataType</link> <RPAREN> ) | ( <link
linkend="prod15">nonReserved</link> <LPAREN> <link
linkend="prod17">expression</link> <COMMA> <link
linkend="prod101">stringConstant</link> <RPAREN> ) | (
<link linkend="prod15">nonReserved</link> <LPAREN>
<link linkend="prod102">intervalType</link> <COMMA>
<link linkend="prod17">expression</link> <COMMA>
<link linkend="prod17">expression</link> <RPAREN> ) |
<link linkend="prod103">queryString</link> | ( (
<LEFT> | <RIGHT> | <CHAR> | <USER>
| <YEAR> | <MONTH> | <HOUR> |
<MINUTE> | <SECOND> | <XMLCONCAT> |
<XMLCOMMENT> ) <LPAREN> ( <link
linkend="prod17">expression</link> !
( <COMMA> <link linkend="prod17">expression</link> )*
)? <RPAREN> ) | ( ( <INSERT> ) <LPAREN> (
<link linkend="prod17">expression</link> ( <COMMA>
<link linkend="prod17">expression</link> )* )?
<RPAREN> ) | ( ( <TRANSLATE> ) <LPAREN> (
<link linkend="prod17">expression</link> ( <COMMA>
<link linkend="prod17">expression</link> )* )?
<RPAREN> ) | <link linkend="prod104">xmlParse</link> |
<link linkend="prod105">xmlElement</link> | ( <XMLPI>
<LPAREN> ( <ID> <link
linkend="prod106">idExpression</link> | <link
linkend="prod106">idExpression</link> ) ( <COMMA>
<link linkend="prod17">expression</link> )? <RPAREN> )
| <link linkend="prod107">xmlForest</link> | <link
linkend="prod68">xmlSerialize</link> | <link
linkend="prod72">xmlQuery</link> | ( <link
linkend="prod2">id</link> <LPAREN> ( <link
linkend="prod17">expression</link> ( <COMMA> <link
linkend="prod17">expression</link> )*!
)? <RPAREN> ) )</para></entry></row>
+( ( <CONVERT> <LPAREN> <link
linkend="prod17">expression</link> <COMMA> <link
linkend="prod32">dataType</link> <RPAREN> ) | (
<CAST> <LPAREN> <link
linkend="prod17">expression</link> <AS> <link
linkend="prod32">dataType</link> <RPAREN> ) | ( <link
linkend="prod15">nonReserved</link> <LPAREN> <link
linkend="prod17">expression</link> <COMMA> <link
linkend="prod103">stringConstant</link> <RPAREN> ) | (
<link linkend="prod15">nonReserved</link> <LPAREN>
<link linkend="prod104">intervalType</link> <COMMA>
<link linkend="prod17">expression</link> <COMMA>
<link linkend="prod17">expression</link> <RPAREN> ) |
<link linkend="prod105">queryString</link> | ( (
<LEFT> | <RIGHT> | <CHAR> | <USER>
| <YEAR> | <MONTH> | <HOUR> |
<MINUTE> | <SECOND> | <XMLCONCAT> |
<XMLCOMMENT> ) <LPAREN> ( <link
linkend="prod17">expression</link> !
( <COMMA> <link linkend="prod17">expression</link> )*
)? <RPAREN> ) | ( ( <INSERT> ) <LPAREN> (
<link linkend="prod17">expression</link> ( <COMMA>
<link linkend="prod17">expression</link> )* )?
<RPAREN> ) | ( ( <TRANSLATE> ) <LPAREN> (
<link linkend="prod17">expression</link> ( <COMMA>
<link linkend="prod17">expression</link> )* )?
<RPAREN> ) | <link linkend="prod106">xmlParse</link> |
<link linkend="prod107">xmlElement</link> | ( <XMLPI>
<LPAREN> ( <ID> <link
linkend="prod108">idExpression</link> | <link
linkend="prod108">idExpression</link> ) ( <COMMA>
<link linkend="prod17">expression</link> )? <RPAREN> )
| <link linkend="prod109">xmlForest</link> | <link
linkend="prod70">xmlSerialize</link> | <link
linkend="prod74">xmlQuery</link> | ( <link
linkend="prod2">id</link> <LPAREN> ( <link
linkend="prod17">expression</link> ( <COMMA> <link
linkend="prod17">expression</link> )*!
)? <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod101"
xreflabel="stringConstant"/>stringConstant</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod103"
xreflabel="stringConstant"/>stringConstant</para></entry>
<entry align="left" valign="top"><para>::=
<link
linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod104"
xreflabel="xmlParse"/>xmlParse</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod106"
xreflabel="xmlParse"/>xmlParse</para></entry>
<entry align="left" valign="top"><para>::=
<XMLPARSE> <LPAREN> <link
linkend="prod15">nonReserved</link> <link
linkend="prod17">expression</link> ( <link
linkend="prod15">nonReserved</link> )?
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod103"
xreflabel="queryString"/>queryString</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod105"
xreflabel="queryString"/>queryString</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod15">nonReserved</link> <LPAREN>
<link linkend="prod17">expression</link> ( <COMMA>
<link linkend="prod56">derivedColumn</link> )*
<RPAREN></para></entry></row>
+<link linkend="prod15">nonReserved</link> <LPAREN>
<link linkend="prod17">expression</link> ( <COMMA>
<link linkend="prod58">derivedColumn</link> )*
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod105"
xreflabel="xmlElement"/>xmlElement</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod107"
xreflabel="xmlElement"/>xmlElement</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLELEMENT> <LPAREN> ( <ID> <link
linkend="prod2">id</link> | <link
linkend="prod2">id</link> ) ( <COMMA> <link
linkend="prod73">xmlNamespaces</link> )? ( <COMMA>
<link linkend="prod108">xmlAttributes</link> )? (
<COMMA> <link linkend="prod17">expression</link> )*
<RPAREN></para></entry></row>
+<XMLELEMENT> <LPAREN> ( <ID> <link
linkend="prod2">id</link> | <link
linkend="prod2">id</link> ) ( <COMMA> <link
linkend="prod75">xmlNamespaces</link> )? ( <COMMA>
<link linkend="prod110">xmlAttributes</link> )? (
<COMMA> <link linkend="prod17">expression</link> )*
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod108"
xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod110"
xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLATTRIBUTES> <LPAREN> <link
linkend="prod56">derivedColumn</link> ( <COMMA> <link
linkend="prod56">derivedColumn</link> )*
<RPAREN></para></entry></row>
+<XMLATTRIBUTES> <LPAREN> <link
linkend="prod58">derivedColumn</link> ( <COMMA> <link
linkend="prod58">derivedColumn</link> )*
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod107"
xreflabel="xmlForest"/>xmlForest</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod109"
xreflabel="xmlForest"/>xmlForest</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLFOREST> <LPAREN> ( <link
linkend="prod73">xmlNamespaces</link> <COMMA> )? <link
linkend="prod56">derivedColumn</link> ( <COMMA> <link
linkend="prod56">derivedColumn</link> )*
<RPAREN></para></entry></row>
+<XMLFOREST> <LPAREN> ( <link
linkend="prod75">xmlNamespaces</link> <COMMA> )? <link
linkend="prod58">derivedColumn</link> ( <COMMA> <link
linkend="prod58">derivedColumn</link> )*
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod73"
xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod75"
xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLNAMESPACES> <LPAREN> <link
linkend="prod109">namespaceItem</link> ( <COMMA> <link
linkend="prod109">namespaceItem</link> )*
<RPAREN></para></entry></row>
+<XMLNAMESPACES> <LPAREN> <link
linkend="prod111">namespaceItem</link> ( <COMMA> <link
linkend="prod111">namespaceItem</link> )*
<RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod109"
xreflabel="namespaceItem"/>namespaceItem</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod111"
xreflabel="namespaceItem"/>namespaceItem</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> <AS>
<link linkend="prod2">id</link>
)</para></entry></row>
<row>
@@ -821,7 +829,7 @@
<entry align="left" valign="top"><para>::=
( <DEFAULT_KEYWORD> <link
linkend="prod1">stringVal</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod106"
xreflabel="idExpression"/>idExpression</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod108"
xreflabel="idExpression"/>idExpression</para></entry>
<entry align="left" valign="top"><para>::=
<link
linkend="prod2">id</link></para></entry></row>
<row>
@@ -829,11 +837,11 @@
<entry align="left" valign="top"><para>::=
( <STRING> | <VARCHAR> | <BOOLEAN> |
<BYTE> | <TINYINT> | <SHORT> |
<SMALLINT> | <CHAR> | <INTEGER> |
<LONG> | <BIGINT> | <BIGINTEGER> |
<FLOAT> | <REAL> | <DOUBLE> |
<BIGDECIMAL> | <DECIMAL> | <DATE> |
<TIME> | <TIMESTAMP> | <OBJECT> |
<BLOB> | <CLOB> | <XML>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod102"
xreflabel="intervalType"/>intervalType</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod104"
xreflabel="intervalType"/>intervalType</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod15">nonReserved</link>
)</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor
id="prod97"
xreflabel="literal"/>literal</para></entry>
+<entry align="right" valign="top"><para><anchor
id="prod99"
xreflabel="literal"/>literal</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> |
<INTEGERVAL> | <FLOATVAL> | <FALSE> |
<TRUE> | <UNKNOWN> | <NULL> | ( (
<BOOLEANTYPE> | <TIMESTAMPTYPE> | <DATETYPE> |
<TIMETYPE> ) <link linkend="prod1">stringVal</link>
<RBRACE> ) )</para></entry></row>
</tbody>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
===================================================================
---
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2010-10-04
21:04:24 UTC (rev 2625)
@@ -401,6 +401,11 @@
<para>A SELECT command has a number of clauses:</para>
<listitem>
<para>
+ <link linkend="with_clause">WITH ...</link>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<link linkend="select_clause">SELECT ...</link>
</para>
</listitem>
@@ -445,6 +450,10 @@
</para>
<itemizedlist>
<listitem>
+ <para>WITH stage - gathers all rows from all with items in the order
listed. Subsequent with items and the main query can reference the a with item as if it
is a table.
+ </para>
+ </listitem>
+ <listitem>
<para>FROM stage - gathers all rows from all tables involved in the query
and logically joins them with a Cartesian product, producing a single large table with all
columns from all tables. Joins and join criteria are then applied to filter rows that do
not match the join structure.
</para>
</listitem>
@@ -482,6 +491,11 @@
named. Because the WHERE clause is processed before the SELECT, the
columns have not yet been named and the aliases are not yet known.
</para>
+ <note>
+ <para>
+ The explicit table syntax <code>TABLE x</code> may be used as a
shortcut for <code>SELECT * FROM x</code>.
+ </para>
+ </note>
</section>
<section id="insert_command">
<title>INSERT Command</title>
@@ -725,10 +739,26 @@
<section>
<title>SQL Clauses</title>
<para>This section describes the clauses that are used in the various <link
linkend="sql_commands">SQL commands</link> described in the previous
section. Nearly all these features follow standard SQL syntax and functionality, so any
SQL reference can be used for more information.</para>
+ <section id="with_clause">
+ <title>WITH Clause</title>
+ <para>
+ Teiid supports non-recursive common table expressions via the WITH clause. With
clause items may be referenced as tables in subsequent with clause items and in the main
query. The WITH clause can be thought of as providing query scoped temporary tables.
+ </para>
+ <para>
+ Usage:
+ <synopsis label="Usage">WITH name [(column, ...)] AS (query
expression) ... </synopsis>
+ </para>
+ <itemizedlist>
+ <para>Syntax Rules:</para>
+ <listitem><para>All of the projected column names must be unique. If
they are not unique, then the column name list must be
provided.</para></listitem>
+ <listitem><para>If the columns of the WITH clause item are declared,
then they must match the number of columns projected by the query
expression.</para></listitem>
+ <listitem><para>Each with clause item must have a unique
name.</para></listitem>
+ </itemizedlist>
+ </section>
<section id="select_clause">
<title>SELECT Clause</title>
<para>
- SQL queries start with the SELECT keyword and are often referred to as "SELECT
statements". Teiid supports most of the standard SQL query constructs.
+ SQL queries that start with the SELECT keyword and are often referred to as
"SELECT statements". Teiid supports most of the standard SQL query constructs.
</para>
<para>
Usage:
Modified:
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -97,6 +97,7 @@
tgtCaps.setCapabilitySupport(Capability.QUERY_AGGREGATES_ENHANCED_NUMERIC,
srcCaps.supportsAggregatesEnhancedNumeric());
tgtCaps.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING,
srcCaps.supportsOrderByNullOrdering());
tgtCaps.setCapabilitySupport(Capability.INSERT_WITH_ITERATOR,
srcCaps.supportsInsertWithIterator());
+ tgtCaps.setCapabilitySupport(Capability.COMMON_TABLE_EXPRESSIONS,
srcCaps.supportsCommonTableExpressions());
List functions = srcCaps.getSupportedFunctions();
if(functions != null && functions.size() > 0) {
Iterator iter = functions.iterator();
Modified:
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -62,6 +62,8 @@
import org.teiid.language.SubqueryComparison;
import org.teiid.language.SubqueryIn;
import org.teiid.language.TableReference;
+import org.teiid.language.With;
+import org.teiid.language.WithItem;
import org.teiid.language.Argument.Direction;
import org.teiid.language.Comparison.Operator;
import org.teiid.language.SortSpecification.Ordering;
@@ -101,6 +103,7 @@
import org.teiid.query.sql.lang.SubquerySetCriteria;
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.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.AliasSymbol;
import org.teiid.query.sql.symbol.Constant;
@@ -169,6 +172,7 @@
result.setRightQuery(translate(union.getRightQuery()));
result.setOrderBy(translate(union.getOrderBy()));
result.setLimit(translate(union.getLimit()));
+ result.setWith(translate(union.getWith()));
return result;
}
@@ -209,8 +213,30 @@
translate(query.getCriteria()), translate(query.getGroupBy()),
translate(query.getHaving()), translate(query.getOrderBy()));
q.setLimit(translate(query.getLimit()));
+ q.setWith(translate(query.getWith()));
return q;
}
+
+ public With translate(List<WithQueryCommand> with) {
+ if (with == null || with.isEmpty()) {
+ return null;
+ }
+ With result = new With();
+ ArrayList<WithItem> items = new ArrayList<WithItem>(with.size());
+ for (WithQueryCommand withQueryCommand : with) {
+ WithItem item = new WithItem();
+ item.setTable(translate(withQueryCommand.getGroupSymbol()));
+ if (withQueryCommand.getColumns() != null) {
+ List<ColumnReference> translatedElements = new
ArrayList<ColumnReference>(withQueryCommand.getColumns().size());
+ for (ElementSymbol es: withQueryCommand.getColumns()) {
+ translatedElements.add(translate(es));
+ }
+ }
+ item.setSubquery(translate(withQueryCommand.getCommand()));
+ }
+ result.setItems(items);
+ return result;
+ }
public TableReference translate(FromClause clause) {
if (clause == null) return null;
Modified: trunk/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -76,6 +76,7 @@
public static final String PROP_NODE_COST_ESTIMATES = "Cost Estimates";
//$NON-NLS-1$
public static final String PROP_ROW_OFFSET = "Row Offset"; //$NON-NLS-1$
public static final String PROP_ROW_LIMIT = "Row Limit"; //$NON-NLS-1$
+ public static final String PROP_WITH = "With"; //$NON-NLS-1$
// XML
public static final String PROP_MESSAGE = "Message"; //$NON-NLS-1$
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -266,9 +266,9 @@
public boolean isScalarGroup() {
return this.metadataType == Type.SCALAR;
}
-
- public void setScalarGroup() {
- this.metadataType = Type.SCALAR;
+
+ public void setMetadataType(Type metadataType) {
+ this.metadataType = metadataType;
}
public List<TempMetadataID> getPrimaryKey() {
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -318,7 +318,8 @@
*/
REQUIRES_CRITERIA,
INSERT_WITH_QUERYEXPRESSION,
- INSERT_WITH_ITERATOR
+ INSERT_WITH_ITERATOR,
+ COMMON_TABLE_EXPRESSIONS
}
public enum Scope {
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -53,11 +53,14 @@
import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.optimizer.QueryOptimizer;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.optimizer.relational.plantree.NodeConstants;
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.NodeFactory;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
+import org.teiid.query.optimizer.relational.rules.CapabilitiesUtil;
+import org.teiid.query.optimizer.relational.rules.CriteriaCapabilityValidatorVisitor;
import org.teiid.query.optimizer.relational.rules.RuleConstants;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.processor.ProcessorPlan;
@@ -68,6 +71,7 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
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;
@@ -91,6 +95,8 @@
import org.teiid.query.sql.lang.SubqueryFromClause;
import org.teiid.query.sql.lang.TableFunctionReference;
import org.teiid.query.sql.lang.UnaryFromClause;
+import org.teiid.query.sql.lang.WithQueryCommand;
+import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
import org.teiid.query.sql.symbol.AllSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
@@ -140,6 +146,53 @@
analysisRecord.println("\n----------------------------------------------------------------------------");
//$NON-NLS-1$
analysisRecord.println("GENERATE CANONICAL: \n" + command);
//$NON-NLS-1$
}
+
+ PlanToProcessConverter planToProcessConverter = null;
+ if (context != null) {
+ planToProcessConverter = context.getPlanToProcessConverter();
+ }
+ if (planToProcessConverter == null) {
+ planToProcessConverter = new PlanToProcessConverter(metadata, idGenerator,
analysisRecord, capFinder);
+ }
+
+ //plan with
+ List<WithQueryCommand> withList = null;
+ Object modelID = null;
+ boolean supportsWithPushdown = true;
+ List<WithQueryCommand> pushDownWith = null;
+ if (command instanceof QueryCommand) {
+ QueryCommand queryCommand = (QueryCommand)command;
+ final HashSet<String> names = new HashSet<String>();
+ if (queryCommand.getWith() != null && !queryCommand.getWith().isEmpty()) {
+ withList = queryCommand.getWith();
+ for (WithQueryCommand with : queryCommand.getWith()) {
+ Command subCommand = with.getCommand();
+ ProcessorPlan procPlan = QueryOptimizer.optimizePlan(subCommand,
metadata, idGenerator, capFinder, analysisRecord, context);
+ subCommand.setProcessorPlan(procPlan);
+ QueryCommand withCommand =
CriteriaCapabilityValidatorVisitor.getQueryCommand(procPlan);
+ if (withCommand != null && supportsWithPushdown) {
+ modelID =
CriteriaCapabilityValidatorVisitor.validateCommandPushdown(modelID, metadata, capFinder,
withCommand);
+ }
+ if (modelID == null) {
+ supportsWithPushdown = false;
+ } else {
+ if (pushDownWith == null) {
+ pushDownWith = new ArrayList<WithQueryCommand>();
+ }
+ WithQueryCommand wqc = new WithQueryCommand(with.getGroupSymbol(),
with.getColumns(), withCommand);
+ pushDownWith.add(wqc);
+ }
+ names.add(with.getGroupSymbol().getCanonicalName());
+ }
+ if (modelID != null && supportsWithPushdown) {
+ supportsWithPushdown =
CapabilitiesUtil.supports(Capability.COMMON_TABLE_EXPRESSIONS, modelID, metadata,
capFinder);
+ }
+ if (supportsWithPushdown) {
+ addModelIds(command, modelID, names);
+ }
+ }
+ }
+
PlanNode plan;
try {
plan = generatePlan(command);
@@ -163,21 +216,46 @@
// Run rule-based optimizer
plan = executeRules(rules, plan);
- PlanToProcessConverter planToProcessConverter = null;
- if (context != null) {
- planToProcessConverter = context.getPlanToProcessConverter();
+ RelationalPlan result = planToProcessConverter.convert(plan);
+ if (withList != null && supportsWithPushdown) {
+ QueryCommand queryCommand =
CriteriaCapabilityValidatorVisitor.getQueryCommand(result);
+ if (queryCommand != null) {
+ if (CriteriaCapabilityValidatorVisitor.validateCommandPushdown(modelID, metadata,
capFinder, queryCommand) == null) {
+ supportsWithPushdown = false;
+ } else {
+ queryCommand.setWith(pushDownWith);
+ }
+ } else {
+ supportsWithPushdown = false;
+ }
}
- if (planToProcessConverter == null) {
- planToProcessConverter = new PlanToProcessConverter(metadata, idGenerator,
analysisRecord, capFinder);
+ if (!supportsWithPushdown) {
+ result.setWith(withList);
}
-
- RelationalPlan result = planToProcessConverter.convert(plan);
-
result.setOutputElements(topCols);
return result;
}
+ /**
+ * mark all relevant group symbols as being from the modelid
+ * @param command
+ * @param modelID
+ * @param names
+ */
+ private void addModelIds(Command command, final Object modelID,
+ final HashSet<String> names) {
+ PreOrPostOrderNavigator.doVisit(command, new LanguageVisitor() {
+ @Override
+ public void visit(UnaryFromClause obj) {
+ GroupSymbol group = obj.getGroup();
+ if (names.contains(group.getNonCorrelationName().toUpperCase())) {
+ group.setModelMetadataId(modelID);
+ }
+ }
+ }, PreOrPostOrderNavigator.POST_ORDER, true);
+ }
+
public void initialize(Command command, IDGenerator idGenerator,
QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
AnalysisRecord analysisRecord, CommandContext context) {
@@ -651,6 +729,9 @@
nestedCommand = resolveVirtualGroup(group);
}
node = NodeFactory.getNewNode(NodeConstants.Types.SOURCE);
+ if (group.getModelMetadataId() != null) {
+ node.setProperty(Info.MODEL_ID, group.getModelMetadataId());
+ }
node.addGroup(group);
if (nestedCommand != null) {
addNestedCommand(node, group, nestedCommand, nestedCommand, true);
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -32,17 +32,18 @@
private Types() {}
static final int NO_TYPE = 0;
- public static final int ACCESS = 2<<0;
- public static final int DUP_REMOVE = 2<<1;
- public static final int JOIN = 2<<2;
- public static final int PROJECT = 2<<3;
- public static final int SELECT = 2<<4;
- public static final int SORT = 2<<5;
- public static final int SOURCE = 2<<6;
- public static final int GROUP = 2<<7;
- public static final int SET_OP = 2<<8;
- public static final int NULL = 2<<9;
- public static final int TUPLE_LIMIT = 2<<10;
+ public static final int ACCESS = 1<<0;
+ public static final int DUP_REMOVE = 1<<1;
+ public static final int JOIN = 1<<2;
+ public static final int PROJECT = 1<<3;
+ public static final int SELECT = 1<<4;
+ public static final int SORT = 1<<5;
+ public static final int SOURCE = 1<<6;
+ public static final int GROUP = 1<<7;
+ public static final int SET_OP = 1<<8;
+ public static final int NULL = 1<<9;
+ public static final int TUPLE_LIMIT = 1<<10;
+ public static final int WITH = 1<<11;
}
/**
@@ -63,6 +64,7 @@
case NodeConstants.Types.SET_OP: return "SetOperation";
//$NON-NLS-1$
case NodeConstants.Types.NULL: return "Null";
//$NON-NLS-1$
case NodeConstants.Types.TUPLE_LIMIT: return "TupleLimit";
//$NON-NLS-1$
+ case NodeConstants.Types.WITH: return "With"; //$NON-NLS-1$
default: return "Unknown: " + type;
//$NON-NLS-1$
}
}
@@ -71,6 +73,7 @@
public enum Info {
ATOMIC_REQUEST, // Command
MODEL_ID, // Object (model ID)
+ IS_COMMON_TABLE,
PROCEDURE_CRITERIA,
PROCEDURE_INPUTS,
PROCEDURE_DEFAULTS,
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 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -52,6 +52,7 @@
import org.teiid.query.sql.lang.MatchCriteria;
import org.teiid.query.sql.lang.NotCriteria;
import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.QueryCommand;
import org.teiid.query.sql.lang.SetCriteria;
import org.teiid.query.sql.lang.SubqueryCompareCriteria;
import org.teiid.query.sql.lang.SubqueryContainer;
@@ -446,45 +447,17 @@
* @return
* @throws TeiidComponentException
*/
- static Object validateSubqueryPushdown(SubqueryContainer subqueryContainer, Object
critNodeModelID, QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
AnalysisRecord analysisRecord) throws TeiidComponentException {
+ public static Object validateSubqueryPushdown(SubqueryContainer subqueryContainer,
Object critNodeModelID,
+ QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord
analysisRecord) throws TeiidComponentException {
ProcessorPlan plan = subqueryContainer.getCommand().getProcessorPlan();
if (plan != null) {
- if(!(plan instanceof RelationalPlan)) {
- return null;
- }
-
- RelationalPlan rplan = (RelationalPlan) plan;
-
- // Check that the plan is just an access node
- RelationalNode accessNode = rplan.getRootNode();
- if(accessNode == null || ! (accessNode instanceof AccessNode) ||
accessNode.getChildren()[0] != null) {
- return null;
- }
-
- // Check that command in access node is a query
- Command command = ((AccessNode)accessNode).getCommand();
- if(command == null || !(command instanceof Query) ||
((Query)command).getIsXML()) {
- return null;
- }
-
- // Check that query in access node is for the same model as current node
- try {
- Collection subQueryGroups =
GroupCollectorVisitor.getGroupsIgnoreInlineViews(command, false);
- if(subQueryGroups.size() == 0) {
- // No FROM?
- return null;
- }
- GroupSymbol subQueryGroup = (GroupSymbol)subQueryGroups.iterator().next();
-
- Object modelID = metadata.getModelID(subQueryGroup.getMetadataID());
- if (critNodeModelID == null) {
- critNodeModelID = modelID;
- } else if(!CapabilitiesUtil.isSameConnector(critNodeModelID, modelID,
metadata, capFinder)) {
- return null;
- }
- } catch(QueryMetadataException e) {
- throw new TeiidComponentException(e,
QueryPlugin.Util.getString("RulePushSelectCriteria.Error_getting_modelID"));
//$NON-NLS-1$
- }
+ QueryCommand queryCommand = getQueryCommand(plan);
+
+ if (queryCommand == null) {
+ return null;
+ }
+
+ critNodeModelID = validateCommandPushdown(critNodeModelID, metadata,
capFinder, queryCommand);
}
if (critNodeModelID == null) {
return null;
@@ -509,6 +482,56 @@
// Found no reason why this node is not eligible
return critNodeModelID;
}
+
+ public static Object validateCommandPushdown(Object critNodeModelID,
+ QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
+ QueryCommand queryCommand) throws TeiidComponentException {
+ // Check that query in access node is for the same model as current node
+ try {
+ Collection subQueryGroups =
GroupCollectorVisitor.getGroupsIgnoreInlineViews(queryCommand, false);
+ if(subQueryGroups.size() == 0) {
+ // No FROM?
+ return null;
+ }
+ GroupSymbol subQueryGroup = (GroupSymbol)subQueryGroups.iterator().next();
+
+ Object modelID = subQueryGroup.getModelMetadataId();
+ if (modelID == null) {
+ modelID = metadata.getModelID(subQueryGroup.getMetadataID());
+ }
+ if (critNodeModelID == null) {
+ critNodeModelID = modelID;
+ } else if(!CapabilitiesUtil.isSameConnector(critNodeModelID, modelID, metadata,
capFinder)) {
+ return null;
+ }
+ } catch(QueryMetadataException e) {
+ throw new TeiidComponentException(e,
QueryPlugin.Util.getString("RulePushSelectCriteria.Error_getting_modelID"));
//$NON-NLS-1$
+ }
+ return critNodeModelID;
+ }
+
+ public static QueryCommand getQueryCommand(ProcessorPlan plan) {
+ if(!(plan instanceof RelationalPlan)) {
+ return null;
+ }
+
+ RelationalPlan rplan = (RelationalPlan) plan;
+
+ // Check that the plan is just an access node
+ RelationalNode accessNode = rplan.getRootNode();
+ if(accessNode == null || ! (accessNode instanceof AccessNode) ||
accessNode.getChildren()[0] != null) {
+ return null;
+ }
+
+ // Check that command in access node is a query
+ Command command = ((AccessNode)accessNode).getCommand();
+ if(command == null || !(command instanceof QueryCommand) || ((command instanceof Query)
&& ((Query)command).getIsXML())) {
+ return null;
+ }
+
+ QueryCommand queryCommand = (QueryCommand)command;
+ return queryCommand;
+ }
private void handleException(TeiidComponentException e) {
this.valid = false;
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -90,6 +90,9 @@
if(nonRelationalPlan != null) {
accessNode.setProperty(NodeConstants.Info.PROCESSOR_PLAN,
nonRelationalPlan);
+ } else if (RuleRaiseAccess.getModelIDFromAccess(accessNode, metadata) ==
null) {
+ //with query
+ accessNode.setProperty(NodeConstants.Info.IS_COMMON_TABLE, Boolean.TRUE);
} else if(command == null) {
PlanNode commandRoot = accessNode;
GroupSymbol intoGroup =
(GroupSymbol)accessNode.getFirstChild().getProperty(NodeConstants.Info.INTO_GROUP);
@@ -106,7 +109,9 @@
command = insertCommand;
}
}
- accessNode.setProperty(NodeConstants.Info.ATOMIC_REQUEST, command);
+ if (command != null) {
+ accessNode.setProperty(NodeConstants.Info.ATOMIC_REQUEST, command);
+ }
accessNode.removeAllChildren();
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -44,7 +44,6 @@
import org.teiid.query.optimizer.relational.plantree.PlanNode;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.lang.Insert;
-import org.teiid.query.sql.lang.TextTable;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
@@ -135,6 +134,11 @@
if (hint != null) {
accessNode.setProperty(NodeConstants.Info.IS_OPTIONAL, hint);
}
+
+ Object modelId = sourceNode.removeProperty(NodeConstants.Info.MODEL_ID);
+ if (modelId != null) {
+ accessNode.setProperty(NodeConstants.Info.MODEL_ID, modelId);
+ }
// Insert
sourceNode.addAsParent(accessNode);
@@ -265,7 +269,7 @@
}
// Create the new symbol
- GroupSymbol newSymbol = (GroupSymbol)oldSymbol.clone();
+ GroupSymbol newSymbol = oldSymbol.clone();
newSymbol.setName(newName);
newSymbol.setDefinition(newDefinition);
return newSymbol;
Modified: trunk/engine/src/main/java/org/teiid/query/processor/BatchIterator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/BatchIterator.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/processor/BatchIterator.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -29,6 +29,7 @@
import org.teiid.common.buffer.TupleBatch;
import org.teiid.common.buffer.TupleBuffer;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.query.processor.BatchCollector.BatchProducer;
@@ -79,7 +80,7 @@
protected List<?> getCurrentTuple() throws TeiidComponentException,
BlockedException, TeiidProcessingException {
List<?> tuple = super.getCurrentTuple();
- if (mark && saveOnMark && this.getCurrentIndex() >
this.buffer.getRowCount()) {
+ if (tuple != null && mark && saveOnMark &&
this.getCurrentIndex() > this.buffer.getRowCount()) {
this.buffer.setRowCount(this.getCurrentIndex() - 1);
this.buffer.addTuple(tuple);
}
@@ -122,14 +123,20 @@
this.buffer.purge();
}
mark = true;
+ if (saveOnMark) {
+ try {
+ getCurrentTuple();
+ } catch (TeiidException e) {
+ }
+ }
}
@Override
public void setPosition(int position) {
- super.setPosition(position);
if (this.buffer == null && position < getCurrentIndex() &&
position < (this.batch != null ? batch.getBeginRow() : Integer.MAX_VALUE)) {
throw new UnsupportedOperationException("Backwards positioning is not
allowed"); //$NON-NLS-1$
}
+ super.setPosition(position);
}
}
Modified:
trunk/engine/src/main/java/org/teiid/query/processor/relational/JoinStrategy.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/relational/JoinStrategy.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/processor/relational/JoinStrategy.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -38,6 +38,9 @@
private int reserved;
public void close() {
+ if (joinNode == null) {
+ return;
+ }
joinNode.getBufferManager().releaseBuffers(reserved);
reserved = 0;
try {
Modified:
trunk/engine/src/main/java/org/teiid/query/processor/relational/PartitionedSortJoin.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/relational/PartitionedSortJoin.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/processor/relational/PartitionedSortJoin.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -63,6 +63,9 @@
@Override
public void close() {
+ if (joinNode == null) {
+ return;
+ }
super.close();
for (TupleBuffer tupleSourceID : this.partitions) {
tupleSourceID.remove();
Modified:
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -22,23 +22,32 @@
package org.teiid.query.processor.relational;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import org.teiid.client.plan.PlanNode;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.TupleBatch;
+import org.teiid.common.buffer.TupleBuffer;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.language.SQLConstants;
+import org.teiid.query.analysis.AnalysisRecord;
+import org.teiid.query.metadata.TempMetadataAdapter;
+import org.teiid.query.processor.BatchCollector;
import org.teiid.query.processor.ProcessorDataManager;
import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.QueryProcessor;
import org.teiid.query.processor.relational.ProjectIntoNode.Mode;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.lang.Create;
+import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.lang.QueryCommand;
+import org.teiid.query.sql.lang.WithQueryCommand;
+import org.teiid.query.tempdata.TempTableStore;
import org.teiid.query.util.CommandContext;
-
/**
*/
public class RelationalPlan extends ProcessorPlan {
@@ -46,6 +55,11 @@
// Initialize state - don't reset
private RelationalNode root;
private List outputCols;
+ private List<WithQueryCommand> with;
+
+ private List<WithQueryCommand> withToProcess;
+ private BatchCollector withBatchCollector;
+ private TempTableStore tempTableStore;
/**
* Constructor for RelationalPlan.
@@ -61,13 +75,26 @@
public void setRootNode(RelationalNode root) {
this.root = root;
}
-
+
+ public void setWith(List<WithQueryCommand> with) {
+ this.with = with;
+ }
+
/**
* @see ProcessorPlan#connectDataManager(ProcessorDataManager)
*/
public void initialize(CommandContext context, ProcessorDataManager dataMgr,
BufferManager bufferMgr) {
- setContext(context);
- connectExternal(this.root, context, dataMgr, bufferMgr);
+ if (this.with != null) {
+ context = context.clone();
+ tempTableStore = new TempTableStore(context.getConnectionID());
+ tempTableStore.setParentTempTableStore(context.getTempTableStore());
+ context.setTempTableStore(tempTableStore);
+ for (WithQueryCommand withCommand : this.with) {
+ withCommand.getCommand().getProcessorPlan().initialize(context, dataMgr,
bufferMgr);
+ }
+ }
+ setContext(context);
+ connectExternal(this.root, context, dataMgr, bufferMgr);
}
private void connectExternal(RelationalNode node, CommandContext context,
ProcessorDataManager dataMgr, BufferManager bufferMgr) {
@@ -94,7 +121,30 @@
public void open()
throws TeiidComponentException, TeiidProcessingException {
-
+ if (this.with != null) {
+ if (withToProcess == null) {
+ withToProcess = new LinkedList<WithQueryCommand>(with);
+ }
+ while (!withToProcess.isEmpty()) {
+ WithQueryCommand withCommand = withToProcess.get(0);
+ if (withBatchCollector == null) {
+ ProcessorPlan plan = withCommand.getCommand().getProcessorPlan();
+ QueryProcessor qp = new QueryProcessor(plan, getContext(),
this.root.getBufferManager(), this.root.getDataManager());
+ withBatchCollector = qp.createBatchCollector();
+ }
+ TupleBuffer tb = withBatchCollector.collectTuples();
+ Create create = new Create();
+ create.setColumns(withCommand.getColumns());
+ create.setTable(withCommand.getGroupSymbol());
+ this.root.getDataManager().registerRequest(getContext(), create,
TempMetadataAdapter.TEMP_MODEL.getID(), null, 0);
+ Insert insert = new Insert(withCommand.getGroupSymbol(), withCommand.getColumns(),
null);
+ insert.setTupleSource(tb.createIndexedTupleSource(true));
+ this.root.getDataManager().registerRequest(getContext(), insert,
TempMetadataAdapter.TEMP_MODEL.getID(), null, 0);
+
this.tempTableStore.setUpdatable(withCommand.getGroupSymbol().getCanonicalName(),
false);
+ withToProcess.remove(0);
+ withBatchCollector = null;
+ }
+ }
this.root.open();
}
@@ -109,7 +159,14 @@
public void close()
throws TeiidComponentException {
-
+ if (this.with != null) {
+ for (WithQueryCommand withCommand : this.with) {
+ withCommand.getCommand().getProcessorPlan().close();
+ }
+ if (this.tempTableStore != null) {
+ this.tempTableStore.removeTempTables();
+ }
+ }
this.root.close();
}
@@ -120,20 +177,47 @@
super.reset();
this.root.reset();
+ if (this.with != null) {
+ withToProcess = null;
+ withBatchCollector = null;
+ for (WithQueryCommand withCommand : this.with) {
+ withCommand.getCommand().getProcessorPlan().reset();
+ }
+ }
}
public String toString() {
- return this.root.toString();
+ StringBuilder sb = new StringBuilder();
+ if (this.with != null) {
+ sb.append(SQLConstants.Reserved.WITH);
+ for (WithQueryCommand withCommand : this.with) {
+ sb.append("\n"); //$NON-NLS-1$
+ sb.append(withCommand.getCommand().getProcessorPlan());
+ }
+ }
+ sb.append(this.root.toString());
+ return sb.toString();
}
public RelationalPlan clone(){
RelationalPlan plan = new RelationalPlan((RelationalNode)root.clone());
- plan.setOutputElements(new ArrayList(( outputCols != null ? outputCols :
Collections.EMPTY_LIST )));
+ plan.setOutputElements(outputCols);
+ if (with != null) {
+ List<WithQueryCommand> newWith = LanguageObject.Util.deepClone(this.with,
WithQueryCommand.class);
+ for (WithQueryCommand withQueryCommand : newWith) {
+ withQueryCommand.getCommand().setProcessorPlan(withQueryCommand.getCommand().getProcessorPlan().clone());
+ }
+ plan.setWith(newWith);
+ }
return plan;
}
public PlanNode getDescriptionProperties() {
- return this.root.getDescriptionProperties();
+ PlanNode node = this.root.getDescriptionProperties();
+ if (this.with != null) {
+ AnalysisRecord.addLanaguageObjects(node, AnalysisRecord.PROP_WITH, this.with);
+ }
+ return node;
}
/**
@@ -145,6 +229,16 @@
@Override
public boolean requiresTransaction(boolean transactionalReads) {
+ if (this.with != null) {
+ if (transactionalReads) {
+ return true;
+ }
+ for (WithQueryCommand withCommand : this.with) {
+ if
(withCommand.getCommand().getProcessorPlan().requiresTransaction(transactionalReads)) {
+ return true;
+ }
+ }
+ }
return requiresTransaction(transactionalReads, root);
}
Modified:
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -37,6 +37,7 @@
import org.teiid.query.metadata.TempMetadataAdapter;
import org.teiid.query.metadata.TempMetadataID;
import org.teiid.query.metadata.TempMetadataStore;
+import org.teiid.query.metadata.TempMetadataID.Type;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.ProcedureReservedWords;
@@ -228,7 +229,7 @@
GroupSymbol variables = new GroupSymbol(name);
externalGroups.addGroup(variables);
TempMetadataID tid = metadata.addTempGroup(name, symbols);
- tid.setScalarGroup();
+ tid.setMetadataType(Type.SCALAR);
variables.setMetadataID(tid);
return variables;
}
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -222,13 +222,17 @@
public static boolean isXMLQuery(Query query, QueryMetadataInterface metadata)
throws TeiidComponentException, QueryMetadataException, QueryResolverException {
+ if (query.getWith() != null && !query.getWith().isEmpty()) {
+ return false;
+ }
+
// Check first group
From from = query.getFrom();
if(from == null){
//select with no from
return false;
}
-
+
if (from.getClauses().size() != 1) {
return false;
}
Modified:
trunk/engine/src/main/java/org/teiid/query/resolver/command/SetQueryResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/SetQueryResolver.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/SetQueryResolver.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -57,6 +57,8 @@
SetQuery setQuery = (SetQuery) command;
+ SimpleQueryResolver.resolveWith(metadata, analysis, setQuery);
+
QueryCommand firstCommand = setQuery.getLeftQuery();
QueryResolver.setChildMetadata(firstCommand, setQuery);
@@ -81,7 +83,7 @@
if (resolveNullLiterals) {
for (int i = 0; i < firstProjectTypes.size(); i++) {
- Class<?> clazz = (Class<?>) firstProjectTypes.get(i);
+ Class<?> clazz = firstProjectTypes.get(i);
if (clazz == null ||
clazz.equals(DataTypeManager.DefaultDataClasses.NULL)) {
firstProjectTypes.set(i, DataTypeManager.DefaultDataClasses.STRING);
@@ -107,7 +109,7 @@
}
private void setProjectedTypes(SetQuery setQuery,
- List firstProjectTypes, QueryMetadataInterface
metadata) throws QueryResolverException {
+ List<Class<?>> firstProjectTypes,
QueryMetadataInterface metadata) throws QueryResolverException {
for (QueryCommand subCommand : setQuery.getQueryCommands()) {
if (!(subCommand instanceof SetQuery)) {
continue;
@@ -117,7 +119,7 @@
if (child.getOrderBy() != null) {
for (int j = 0; j < projectedSymbols.size(); j++) {
SingleElementSymbol ses =
(SingleElementSymbol)projectedSymbols.get(j);
- Class targetType = (Class)firstProjectTypes.get(j);
+ Class<?> targetType = firstProjectTypes.get(j);
if (ses.getType() != targetType &&
orderByContainsVariable(child.getOrderBy(), ses, j)) {
String sourceTypeName =
DataTypeManager.getDataTypeName(ses.getType());
String targetTypeName =
DataTypeManager.getDataTypeName(targetType);
Modified:
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -61,6 +61,7 @@
import org.teiid.query.sql.lang.JoinPredicate;
import org.teiid.query.sql.lang.JoinType;
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.StoredProcedure;
@@ -71,6 +72,7 @@
import org.teiid.query.sql.lang.TableFunctionReference;
import org.teiid.query.sql.lang.TextTable;
import org.teiid.query.sql.lang.UnaryFromClause;
+import org.teiid.query.sql.lang.WithQueryCommand;
import org.teiid.query.sql.lang.XMLTable;
import org.teiid.query.sql.navigator.PostOrderNavigator;
import org.teiid.query.sql.symbol.AliasSymbol;
@@ -95,7 +97,9 @@
public void resolveCommand(Command command, TempMetadataAdapter metadata,
AnalysisRecord analysis, boolean resolveNullLiterals)
throws QueryMetadataException, QueryResolverException, TeiidComponentException {
- Query query = (Query) command;
+ Query query = (Query) command;
+
+ resolveWith(metadata, analysis, query);
try {
QueryResolverVisitor qrv = new QueryResolverVisitor(query, metadata,
analysis);
@@ -133,6 +137,58 @@
}
}
+ static void resolveWith(TempMetadataAdapter metadata,
+ AnalysisRecord analysis, QueryCommand query) throws QueryResolverException,
TeiidComponentException {
+ if (query.getWith() == null || query.getWith().isEmpty()) {
+ return;
+ }
+ LinkedHashSet<GroupSymbol> discoveredGroups = new
LinkedHashSet<GroupSymbol>();
+ for (WithQueryCommand obj : query.getWith()) {
+ QueryCommand queryExpression = obj.getCommand();
+
+ QueryResolver.setChildMetadata(queryExpression, query);
+
+ try {
+ QueryResolver.resolveCommand(queryExpression, Collections.EMPTY_MAP,
metadata.getMetadata(), analysis, false);
+ } catch (TeiidException err) {
+ throw new TeiidRuntimeException(err);
+ }
+
+ if (!discoveredGroups.add(obj.getGroupSymbol())) {
+ throw new QueryResolverException("Duplicate WITH clause item name
{0}");
+ }
+ List<? extends SingleElementSymbol> projectedSymbols =
obj.getCommand().getProjectedSymbols();
+ if (obj.getColumns() != null && !obj.getColumns().isEmpty()) {
+ if (obj.getColumns().size() != projectedSymbols.size()) {
+ throw new QueryResolverException("The number of WITH clause columns
for item {0} do not match the query expression");
+ }
+ Iterator<ElementSymbol> iter = obj.getColumns().iterator();
+ for (SingleElementSymbol singleElementSymbol : projectedSymbols) {
+ ElementSymbol es = iter.next();
+ es.setType(singleElementSymbol.getType());
+ }
+ projectedSymbols = obj.getColumns();
+ }
+ TempMetadataID id = ResolverUtil.addTempGroup(metadata, obj.getGroupSymbol(),
projectedSymbols, true);
+
obj.getGroupSymbol().setMetadataID(metadata.getMetadataStore().getTempGroupID(obj.getGroupSymbol().getName()));
+ obj.getGroupSymbol().setIsTempTable(true);
+ List<GroupSymbol> groups =
Collections.singletonList(obj.getGroupSymbol());
+ if (obj.getColumns() != null && !obj.getColumns().isEmpty()) {
+ for (SingleElementSymbol singleElementSymbol : projectedSymbols) {
+ ResolverVisitor.resolveLanguageObject(singleElementSymbol, groups,
metadata);
+ }
+ }
+ if (obj.getColumns() != null && !obj.getColumns().isEmpty()) {
+ Iterator<ElementSymbol> iter = obj.getColumns().iterator();
+ for (TempMetadataID colid : id.getElements()) {
+ ElementSymbol es = iter.next();
+ es.setMetadataID(colid);
+ es.setGroupSymbol(obj.getGroupSymbol());
+ }
+ }
+ }
+ }
+
private static GroupSymbol resolveAllInGroup(AllInGroupSymbol allInGroupSymbol,
Set<GroupSymbol> groups, QueryMetadataInterface metadata) throws
QueryResolverException, QueryMetadataException, TeiidComponentException {
String name = allInGroupSymbol.getName();
int index = name.lastIndexOf(ALL_IN_GROUP_SUFFIX);
@@ -197,7 +253,7 @@
}
}
- private void resolveSubQuery(SubqueryContainer obj, Collection<GroupSymbol>
externalGroups) {
+ private void resolveSubQuery(SubqueryContainer<?> obj,
Collection<GroupSymbol> externalGroups) {
Command command = obj.getCommand();
QueryResolver.setChildMetadata(command, query);
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -486,7 +486,7 @@
GroupInfo groupInfo = (GroupInfo)metadata.getFromMetadataCache(group.getMetadataID(),
key);
if (groupInfo == null) {
- group = (GroupSymbol)group.clone();
+ group = group.clone();
// get all elements from the metadata
List elementIDs = metadata.getElementIDsInGroupID(group.getMetadataID());
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -111,6 +111,7 @@
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.XMLTable;
import org.teiid.query.sql.lang.PredicateCriteria.Negatable;
import org.teiid.query.sql.navigator.PostOrderNavigator;
@@ -231,17 +232,24 @@
switch(command.getType()) {
case Command.TYPE_QUERY:
+ QueryCommand queryCommand = (QueryCommand)command;
+ if (removeOrderBy && queryCommand.getLimit() == null) {
+ queryCommand.setOrderBy(null);
+ }
+ if (queryCommand.getWith() != null) {
+ for (WithQueryCommand withQueryCommand : queryCommand.getWith()) {
+ if (withQueryCommand.getColumns() == null) {
+ List<ElementSymbol> columns =
ResolverUtil.resolveElementsInGroup(withQueryCommand.getGroupSymbol(), metadata);
+ withQueryCommand.setColumns(LanguageObject.Util.deepClone(columns,
ElementSymbol.class));
+ }
+ rewriteSubqueryContainer(withQueryCommand, true);
+ }
+ }
if(command instanceof Query) {
command = rewriteQuery((Query) command);
}else {
command = rewriteSetQuery((SetQuery) command);
}
- if (removeOrderBy) {
- QueryCommand queryCommand = (QueryCommand)command;
- if (queryCommand.getLimit() == null) {
- queryCommand.setOrderBy(null);
- }
- }
break;
case Command.TYPE_STORED_PROCEDURE:
command = rewriteExec((StoredProcedure) command);
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageObject.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageObject.java 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageObject.java 2010-10-04 21:04:24
UTC (rev 2625)
@@ -48,6 +48,9 @@
public static class Util {
public static <S extends LanguageObject, T extends S> ArrayList<S>
deepClone(List<T> collection, Class<S> type) {
+ if (collection == null) {
+ return null;
+ }
ArrayList<S> result = new ArrayList<S>(collection.size());
for (LanguageObject obj : collection) {
result.add(type.cast(obj.clone()));
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -33,6 +33,7 @@
* the public visit methods should be overridden to provide the visitor functionality.
* These public visit methods SHOULD NOT be called directly.</p>
*/
+@SuppressWarnings("unused")
public abstract class LanguageVisitor {
private boolean abort = false;
@@ -135,4 +136,5 @@
public void visit(QueryString obj) {}
public void visit(XMLParse obj) {}
public void visit(ExpressionCriteria obj) {}
+ public void visit(WithQueryCommand obj) {}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/Insert.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/Insert.java 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Insert.java 2010-10-04 21:04:24
UTC (rev 2625)
@@ -162,7 +162,7 @@
* Set a collection of variables that replace the existing variables
* @param vars Variables to be set on this object (ElementSymbols)
*/
- public void setVariables(Collection vars) {
+ public void setVariables(Collection<ElementSymbol> vars) {
this.variables.clear();
this.variables.addAll(vars);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java 2010-10-04 19:26:58 UTC
(rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java 2010-10-04 21:04:24 UTC
(rev 2625)
@@ -349,6 +349,8 @@
if(getLimit() != null) {
copy.setLimit( (Limit) getLimit().clone());
}
+
+ copy.setWith(LanguageObject.Util.deepClone(this.getWith(),
WithQueryCommand.class));
// Defect 13751: should clone isXML state.
copy.setIsXML(getIsXML());
@@ -391,6 +393,7 @@
EquivalenceUtil.areEqual(getHaving(), other.getHaving()) &&
EquivalenceUtil.areEqual(getOrderBy(), other.getOrderBy()) &&
EquivalenceUtil.areEqual(getLimit(), other.getLimit()) &&
+ EquivalenceUtil.areEqual(getWith(), other.getWith()) &&
getIsXML() == other.getIsXML() &&
sameOptionAndHint(other);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/QueryCommand.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/QueryCommand.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/QueryCommand.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -22,8 +22,10 @@
package org.teiid.query.sql.lang;
+import java.util.List;
+
/**
* This is a common super class for the two types of query commands: Query and SetQuery.
* This class provides some useful commonalities when the type of query command
@@ -36,6 +38,8 @@
/** Limit on returned rows */
private Limit limit;
+
+ private List<WithQueryCommand> with;
/**
* Get the order by clause for the query.
@@ -61,5 +65,13 @@
this.limit = limit;
}
+ public List<WithQueryCommand> getWith() {
+ return with;
+ }
+
+ public void setWith(List<WithQueryCommand> with) {
+ this.with = with;
+ }
+
public abstract Query getProjectedQuery();
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/SetQuery.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/SetQuery.java 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/SetQuery.java 2010-10-04 21:04:24
UTC (rev 2625)
@@ -34,6 +34,7 @@
import org.teiid.core.util.HashCodeUtil;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.resolver.util.ResolverUtil;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.symbol.AliasSymbol;
import org.teiid.query.sql.symbol.Expression;
@@ -175,13 +176,15 @@
copy.setAll(this.all);
if(this.getOrderBy() != null) {
- copy.setOrderBy( (OrderBy) this.getOrderBy().clone() );
+ copy.setOrderBy(this.getOrderBy().clone());
}
if(this.getLimit() != null) {
copy.setLimit( (Limit) this.getLimit().clone() );
}
+ copy.setWith(LanguageObject.Util.deepClone(this.getWith(),
WithQueryCommand.class));
+
if (this.projectedTypes != null) {
copy.setProjectedTypes(new ArrayList<Class<?>>(projectedTypes),
this.metadata);
}
@@ -213,6 +216,7 @@
EquivalenceUtil.areEqual(this.rightQuery, other.rightQuery) &&
EquivalenceUtil.areEqual(getOrderBy(), other.getOrderBy()) &&
EquivalenceUtil.areEqual(getLimit(), other.getLimit()) &&
+ EquivalenceUtil.areEqual(getWith(), other.getWith()) &&
sameOptionAndHint(other);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/SubqueryContainer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/SubqueryContainer.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/SubqueryContainer.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -26,18 +26,18 @@
* This interface defines a common interface for all MetaMatrix SQL objects
* that contain subqueries.
*/
-public interface SubqueryContainer {
+public interface SubqueryContainer<T extends Command> {
/**
* Returns the subquery Command object
* @return the subquery Command object
*/
- Command getCommand();
+ T getCommand();
/**
* Sets the subquery Command object
* @param command the subquery Command object
*/
- void setCommand(Command command);
+ void setCommand(T command);
}
Added: trunk/engine/src/main/java/org/teiid/query/sql/lang/WithQueryCommand.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/WithQueryCommand.java
(rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/WithQueryCommand.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -0,0 +1,79 @@
+package org.teiid.query.sql.lang;
+
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.visitor.SQLStringVisitor;
+
+public class WithQueryCommand implements LanguageObject,
SubqueryContainer<QueryCommand> {
+
+ private GroupSymbol groupSymbol;
+ private List<ElementSymbol> columns;
+ private QueryCommand queryExpression;
+
+ public WithQueryCommand(GroupSymbol groupSymbol, List<ElementSymbol> columns,
QueryCommand queryExpression) {
+ this.groupSymbol = groupSymbol;
+ this.columns = columns;
+ this.queryExpression = queryExpression;
+ }
+
+ public GroupSymbol getGroupSymbol() {
+ return groupSymbol;
+ }
+
+ public void setColumns(List<ElementSymbol> columns) {
+ this.columns = columns;
+ }
+
+ public List<ElementSymbol> getColumns() {
+ return columns;
+ }
+
+ @Override
+ public QueryCommand getCommand() {
+ return queryExpression;
+ }
+
+ public void setCommand(QueryCommand command) {
+ this.queryExpression = command;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public WithQueryCommand clone() {
+ return new WithQueryCommand(groupSymbol.clone(), LanguageObject.Util.deepClone(columns,
ElementSymbol.class), (QueryCommand)queryExpression.clone());
+ }
+
+ @Override
+ public int hashCode() {
+ return groupSymbol.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof WithQueryCommand)) {
+ return false;
+ }
+ WithQueryCommand other = (WithQueryCommand)obj;
+ return EquivalenceUtil.areEqual(groupSymbol, other.getGroupSymbol()) &&
+ EquivalenceUtil.areEqual(this.columns, other.getColumns()) &&
+ EquivalenceUtil.areEqual(this.queryExpression, other.queryExpression);
+ }
+
+ @Override
+ public String toString() {
+ return SQLStringVisitor.getSQLString(this);
+ }
+
+}
Property changes on:
trunk/engine/src/main/java/org/teiid/query/sql/lang/WithQueryCommand.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPostOrderNavigator.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPostOrderNavigator.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPostOrderNavigator.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -24,46 +24,17 @@
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.lang.ExistsCriteria;
-import org.teiid.query.sql.lang.SubqueryCompareCriteria;
-import org.teiid.query.sql.lang.SubqueryFromClause;
-import org.teiid.query.sql.lang.SubquerySetCriteria;
-import org.teiid.query.sql.symbol.ScalarSubquery;
/**
* @since 4.2
*/
-public class DeepPostOrderNavigator extends PostOrderNavigator {
+public class DeepPostOrderNavigator extends PreOrPostOrderNavigator {
public DeepPostOrderNavigator(LanguageVisitor visitor) {
- super(visitor);
+ super(visitor, PreOrPostOrderNavigator.POST_ORDER, true);
}
- public void visit(ExistsCriteria obj) {
- visitNode(obj.getCommand());
- visitVisitor(obj);
- }
- public void visit(ScalarSubquery obj) {
- visitNode(obj.getCommand());
- visitVisitor(obj);
- }
- public void visit(SubqueryCompareCriteria obj) {
- visitNode(obj.getLeftExpression());
- visitNode(obj.getCommand());
- visitVisitor(obj);
- }
- public void visit(SubqueryFromClause obj) {
- visitNode(obj.getCommand());
- visitNode(obj.getGroupSymbol());
- visitVisitor(obj);
- }
- public void visit(SubquerySetCriteria obj) {
- visitNode(obj.getCommand());
- visitNode(obj.getExpression());
- visitVisitor(obj);
- }
-
public static void doVisit(LanguageObject object, LanguageVisitor visitor) {
DeepPostOrderNavigator nav = new DeepPostOrderNavigator(visitor);
object.acceptVisitor(nav);
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -24,68 +24,21 @@
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.lang.ExistsCriteria;
-import org.teiid.query.sql.lang.SubqueryCompareCriteria;
-import org.teiid.query.sql.lang.SubqueryFromClause;
-import org.teiid.query.sql.lang.SubquerySetCriteria;
-import org.teiid.query.sql.proc.CommandStatement;
-import org.teiid.query.sql.proc.LoopStatement;
-import org.teiid.query.sql.symbol.ScalarSubquery;
/**
* @since 4.2
*/
-public class DeepPreOrderNavigator extends PreOrderNavigator {
+public class DeepPreOrderNavigator extends PreOrPostOrderNavigator {
/**
* @param visitor
* @since 4.2
*/
public DeepPreOrderNavigator(LanguageVisitor visitor) {
- super(visitor);
+ super(visitor, PreOrPostOrderNavigator.PRE_ORDER, true);
}
-
- public void visit(ExistsCriteria obj) {
- visitVisitor(obj);
- visitNode(obj.getCommand());
- }
- public void visit(ScalarSubquery obj) {
- visitVisitor(obj);
- visitNode(obj.getCommand());
- }
- public void visit(SubqueryCompareCriteria obj) {
- visitVisitor(obj);
- visitNode(obj.getLeftExpression());
- visitNode(obj.getCommand());
- }
- public void visit(SubqueryFromClause obj) {
- visitVisitor(obj);
- visitNode(obj.getCommand());
- visitNode(obj.getGroupSymbol());
- }
- public void visit(SubquerySetCriteria obj) {
- visitVisitor(obj);
- visitNode(obj.getCommand());
- visitNode(obj.getExpression());
- }
-
- @Override
- public void visit(CommandStatement obj) {
- visitVisitor(obj);
- visitNode(obj.getCommand());
- visitVisitor(obj);
- }
-
- @Override
- public void visit(LoopStatement obj) {
- visitVisitor(obj);
- visitNode(obj.getCommand());
- visitNode(obj.getBlock());
- visitVisitor(obj);
- }
-
public static void doVisit(LanguageObject object, LanguageVisitor visitor) {
DeepPreOrderNavigator nav = new DeepPreOrderNavigator(visitor);
object.acceptVisitor(nav);
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PostOrderNavigator.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PostOrderNavigator.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PostOrderNavigator.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -32,7 +32,7 @@
public class PostOrderNavigator extends PreOrPostOrderNavigator {
public PostOrderNavigator(LanguageVisitor visitor) {
- super(visitor, POST_ORDER);
+ super(visitor, POST_ORDER, false);
}
public static void doVisit(LanguageObject object, LanguageVisitor visitor) {
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -65,6 +65,7 @@
import org.teiid.query.sql.lang.TextTable;
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.XMLTable;
import org.teiid.query.sql.proc.AssignmentStatement;
import org.teiid.query.sql.proc.Block;
@@ -115,10 +116,12 @@
public static final boolean POST_ORDER = false;
private boolean order;
+ private boolean deep;
- public PreOrPostOrderNavigator(LanguageVisitor visitor, boolean order) {
+ public PreOrPostOrderNavigator(LanguageVisitor visitor, boolean order, boolean deep)
{
super(visitor);
this.order = order;
+ this.deep = deep;
}
protected void preVisitVisitor(LanguageObject obj) {
@@ -192,6 +195,9 @@
}
public void visit(CommandStatement obj) {
preVisitVisitor(obj);
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
postVisitVisitor(obj);
}
public void visit(CompareCriteria obj) {
@@ -247,6 +253,9 @@
}
public void visit(ExistsCriteria obj) {
preVisitVisitor(obj);
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
postVisitVisitor(obj);
}
public void visit(ExpressionSymbol obj) {
@@ -343,6 +352,9 @@
}
public void visit(LoopStatement obj) {
preVisitVisitor(obj);
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
visitNode(obj.getBlock());
postVisitVisitor(obj);
}
@@ -396,6 +408,9 @@
}
public void visit(ScalarSubquery obj) {
preVisitVisitor(obj);
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
postVisitVisitor(obj);
}
public void visit(SearchedCaseExpression obj) {
@@ -445,16 +460,25 @@
public void visit(SubqueryCompareCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getLeftExpression());
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
postVisitVisitor(obj);
}
public void visit(SubqueryFromClause obj) {
preVisitVisitor(obj);
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
visitNode(obj.getGroupSymbol());
postVisitVisitor(obj);
}
public void visit(SubquerySetCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
postVisitVisitor(obj);
}
public void visit(TranslateCriteria obj) {
@@ -608,8 +632,22 @@
postVisitVisitor(obj);
}
+ @Override
+ public void visit(WithQueryCommand obj) {
+ preVisitVisitor(obj);
+ visitNodes(obj.getColumns());
+ if (deep) {
+ visitNode(obj.getCommand());
+ }
+ postVisitVisitor(obj);
+ }
+
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean
order) {
- PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, order);
+ doVisit(object, visitor, order, false);
+ }
+
+ public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean
order, boolean deep) {
+ PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, order, deep);
object.acceptVisitor(nav);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrderNavigator.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrderNavigator.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrderNavigator.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -32,7 +32,7 @@
public class PreOrderNavigator extends PreOrPostOrderNavigator {
public PreOrderNavigator(LanguageVisitor visitor) {
- super(visitor, PRE_ORDER);
+ super(visitor, PRE_ORDER, false);
}
public static void doVisit(LanguageObject object, LanguageVisitor visitor) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -51,6 +51,8 @@
private boolean isGlobalTable;
private boolean isProcedure;
+ private Object modelMetadataId;
+
private String outputDefinition;
/**
@@ -85,6 +87,14 @@
setDefinition(definition);
}
+ public Object getModelMetadataId() {
+ return modelMetadataId;
+ }
+
+ public void setModelMetadataId(Object modelMetadataId) {
+ this.modelMetadataId = modelMetadataId;
+ }
+
public String getNonCorrelationName() {
if (this.definition == null) {
return this.getName();
@@ -177,7 +187,7 @@
* Return a deep copy of this object.
* @return Deep copy of the object
*/
- public Object clone() {
+ public GroupSymbol clone() {
GroupSymbol copy = new GroupSymbol(getName(), getCanonical(), getDefinition());
if(getMetadataID() != null) {
copy.setMetadataID(getMetadataID());
@@ -187,6 +197,7 @@
copy.setOutputDefinition(this.getOutputDefinition());
copy.setOutputName(this.getOutputName());
copy.isGlobalTable = isGlobalTable;
+ copy.modelMetadataId = modelMetadataId;
return copy;
}
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -40,7 +40,7 @@
public static class AggregateStopNavigator extends PreOrPostOrderNavigator {
public AggregateStopNavigator(LanguageVisitor visitor) {
- super(visitor, PreOrPostOrderNavigator.POST_ORDER);
+ super(visitor, PreOrPostOrderNavigator.POST_ORDER, false);
}
public void visit(AggregateSymbol obj) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -79,6 +79,7 @@
import org.teiid.query.sql.lang.TextTable;
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.XMLTable;
import org.teiid.query.sql.lang.TextTable.TextColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
@@ -631,13 +632,7 @@
append(SPACE);
append(BY);
append(SPACE);
- for (Iterator<OrderByItem> iterator = obj.getOrderByItems().iterator();
iterator.hasNext();) {
- OrderByItem item = iterator.next();
- visitNode(item);
- if (iterator.hasNext()) {
- append(", "); //$NON-NLS-1$
- }
- }
+ registerNodes(obj.getOrderByItems(), 0);
}
@Override
@@ -725,9 +720,27 @@
append(" = "); //$NON-NLS-1$
visitNode(obj.getValue());
}
+
+ @Override
+ public void visit(WithQueryCommand obj) {
+ visitNode(obj.getGroupSymbol());
+ append(SPACE);
+ if (obj.getColumns() != null && !obj.getColumns().isEmpty()) {
+ append(Tokens.LPAREN);
+ registerNodes(obj.getColumns(), 0);
+ append(Tokens.RPAREN);
+ append(SPACE);
+ }
+ append(AS);
+ append(SPACE);
+ append(Tokens.LPAREN);
+ visitNode(obj.getCommand());
+ append(Tokens.RPAREN);
+ }
public void visit( Query obj ) {
- addCacheHint(obj.getCacheHint());
+ addCacheHint(obj.getCacheHint());
+ addWithClause(obj);
visitNode(obj.getSelect());
if (obj.getInto() != null) {
@@ -776,6 +789,15 @@
}
}
+ private void addWithClause(QueryCommand obj) {
+ if (obj.getWith() != null && !obj.getWith().isEmpty()) {
+ append(WITH);
+ append(SPACE);
+ registerNodes(obj.getWith(), 0);
+ beginClause(0);
+ }
+ }
+
protected void visitCriteria( String keyWord,
Criteria crit ) {
append(keyWord);
@@ -858,6 +880,7 @@
public void visit( SetQuery obj ) {
addCacheHint(obj.getCacheHint());
+ addWithClause(obj);
QueryCommand query = obj.getLeftQuery();
appendSetQuery(obj, query, false);
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ValueIteratorProviderCollectorVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ValueIteratorProviderCollectorVisitor.java 2010-10-04
19:26:58 UTC (rev 2624)
+++
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ValueIteratorProviderCollectorVisitor.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -34,6 +34,7 @@
import org.teiid.query.sql.lang.SubqueryCompareCriteria;
import org.teiid.query.sql.lang.SubqueryContainer;
import org.teiid.query.sql.lang.SubquerySetCriteria;
+import org.teiid.query.sql.lang.WithQueryCommand;
import org.teiid.query.sql.navigator.PreOrderNavigator;
import org.teiid.query.sql.symbol.ScalarSubquery;
@@ -114,6 +115,11 @@
public void visit(ScalarSubquery obj) {
this.valueIteratorProviders.add(obj);
}
+
+ @Override
+ public void visit(WithQueryCommand obj) {
+ this.valueIteratorProviders.add(obj);
+ }
/**
* Helper to quickly get the ValueIteratorProvider instances from obj
Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -196,6 +196,13 @@
}
}
+ public void setUpdatable(String name, boolean updatable) {
+ TempTable table = groupToTupleSourceID.get(name);
+ if (table != null) {
+ table.setUpdatable(updatable);
+ }
+ }
+
TempTable getOrCreateTempTable(String tempTableID, Command command, BufferManager
buffer, boolean delegate) throws QueryProcessingException{
TempTable tsID = groupToTupleSourceID.get(tempTableID);
if(tsID != null) {
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2010-10-04 21:04:24
UTC (rev 2625)
@@ -1286,8 +1286,8 @@
{
Insert insert = new Insert();
String group = null;
- String element = null;
List values = null;
+ List<ElementSymbol> columns = null;
Option option = null;
QueryCommand query = null;
}
@@ -1295,20 +1295,9 @@
<INSERT> <INTO>
group = id()
- [LOOKAHEAD(<LPAREN><ID>)
- <LPAREN>
- element = id()
- {
- insert.addVariable(new ElementSymbol(element));
- }
- ( <COMMA>
- element = id()
- {
- insert.addVariable(new ElementSymbol(element));
- }
- )*
- <RPAREN>
- ]
+ [LOOKAHEAD(<LPAREN><ID>) columns = columnList(false) {
+ insert.setVariables(columns);
+ }]
(
( <VALUES>
@@ -1340,6 +1329,35 @@
}
}
+List<ElementSymbol> columnList(boolean validate) :
+{
+ String element = null;
+ List<ElementSymbol> symbols = new LinkedList<ElementSymbol>();
+}
+{
+ <LPAREN>
+ element = id()
+ {
+ if (validate) {
+ element = validateElementName(element);
+ }
+ symbols.add(new ElementSymbol(element));
+ }
+ ( <COMMA>
+ element = id()
+ {
+ if (validate) {
+ element = validateElementName(element);
+ }
+ symbols.add(new ElementSymbol(element));
+ }
+ )*
+ <RPAREN>
+ {
+ return symbols;
+ }
+}
+
/**
* Parse row values - this is a comma separated list of values.
* @return List of values, never null
@@ -1446,14 +1464,44 @@
QueryCommand queryExpression(ParseInfo info) :
{
QueryCommand query = null;
+ List<WithQueryCommand> withList = null;
+ WithQueryCommand withQueryCommand = null;
}
{
+ [<WITH> withQueryCommand = withListElement(info)
+ {
+ withList = new LinkedList<WithQueryCommand>();
+ withList.add(withQueryCommand);
+ }
+ ( <COMMA>
+ withQueryCommand = withListElement(info)
+ {
+ withList.add(withQueryCommand);
+ }
+ )*
+ ]
query = queryExpressionBody(info)
{
+ query.setWith(withList);
return query;
}
}
+WithQueryCommand withListElement(ParseInfo info) :
+{
+ String name = null;
+ List<ElementSymbol> columns = null;
+ QueryCommand queryExpression = null;
+}
+{
+ name = id()
+ [ columns = columnList(true)]
+ <AS> <LPAREN> queryExpression = queryExpression(info) <RPAREN>
+ {
+ return new WithQueryCommand(new GroupSymbol(validateAlias(name)), columns,
queryExpression);
+ }
+}
+
QueryCommand queryExpressionBody(ParseInfo info) :
{
QueryCommand query = null;
@@ -1506,10 +1554,17 @@
QueryCommand queryPrimary(ParseInfo info) :
{
QueryCommand query = null;
+ String name = null;
}
{
(
query=query(info) |
+ (<TABLE> name=id() {
+ Query q = new Query();
+ q.setSelect(new Select(Arrays.asList(new AllSymbol())));
+ q.setFrom(new From(Arrays.asList(new UnaryFromClause(new
GroupSymbol(name)))));
+ query = q;
+ }) |
(<LPAREN> query=queryExpressionBody(info) <RPAREN>)
)
{
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2010-10-04 19:26:58
UTC (rev 2624)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2010-10-04 21:04:24
UTC (rev 2625)
@@ -78,6 +78,7 @@
import org.teiid.query.sql.lang.TextTable;
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.XMLTable;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.lang.TextTable.TextColumn;
@@ -6857,5 +6858,21 @@
SearchedCaseExpression sce = new SearchedCaseExpression(Arrays.asList(new
NotCriteria(new ExpressionCriteria(new ElementSymbol("x")))), Arrays.asList(new
ElementSymbol("y")));
helpTestExpression("case when not x then y end", "CASE WHEN NOT (x)
THEN y END", sce);
}
+
+ @Test public void testWithClause() throws Exception {
+ Query query = getOrderByQuery(null);
+ query.setWith(Arrays.asList(new WithQueryCommand(new GroupSymbol("x"),
null, getOrderByQuery(null))));
+ helpTest("WITH x AS (SELECT a FROM db.g WHERE b = aString) SELECT a FROM
db.g WHERE b = aString", "WITH x AS (SELECT a FROM db.g WHERE b = aString)
SELECT a FROM db.g WHERE b = aString", query); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Test public void testExplicitTable() throws Exception {
+ Query query = new Query();
+ Select select = new Select();
+ query.setSelect(select);
+ select.addSymbol(new AllSymbol());
+ From from = new From(Arrays.asList(new UnaryFromClause(new
GroupSymbol("X"))));
+ query.setFrom(from);
+ helpTest("TABLE X", "SELECT * FROM X", query);
+ }
}
Added: trunk/engine/src/test/java/org/teiid/query/processor/TestWithClauseProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestWithClauseProcessing.java
(rev 0)
+++
trunk/engine/src/test/java/org/teiid/query/processor/TestWithClauseProcessing.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -0,0 +1,73 @@
+package org.teiid.query.processor;
+
+import static org.teiid.query.processor.TestProcessor.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.teiid.core.TeiidException;
+import org.teiid.query.optimizer.TestOptimizer;
+import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
+import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
+import org.teiid.query.unittest.FakeMetadataFactory;
+
+@SuppressWarnings({"nls", "unchecked"})
+public class TestWithClauseProcessing {
+
+ @Test public void testSingleItem() {
+ String sql = "with a (x, y, z) as (select e1, e2, e3 from pm1.g1) SELECT
pm1.g2.e2, a.x from pm1.g2, a where e1 = x and z = 1 order by x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList(0, "a"),
+ Arrays.asList(3, "a"),
+ Arrays.asList(0, "a"),
+ Arrays.asList(1, "c"),
+ };
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+
+ ProcessorPlan plan = helpGetPlan(helpParse(sql),
FakeMetadataFactory.example1Cached());
+
+ helpProcess(plan, dataManager, expected);
+ }
+
+ @Test public void testMultipleItems() {
+ String sql = "with a (x, y, z) as (select e1, e2, e3 from pm1.g1), b as (SELECT
* from pm1.g2, a where e1 = x and z = 1 order by e2 limit 2) SELECT a.x, b.e1 from a, b
where a.x = b.e1"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList("a", "a"),
+ Arrays.asList("a", "a"),
+ Arrays.asList("a", "a"),
+ Arrays.asList("a", "a"),
+ Arrays.asList("a", "a"),
+ Arrays.asList("a", "a"),
+ };
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+
+ ProcessorPlan plan = helpGetPlan(helpParse(sql),
FakeMetadataFactory.example1Cached());
+
+ helpProcess(plan, dataManager, expected);
+ }
+
+ @Test public void testWithPushdown() throws TeiidException {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+ caps.setCapabilitySupport(Capability.COMMON_TABLE_EXPRESSIONS, true);
+ caps.setCapabilitySupport(Capability.QUERY_FROM_JOIN_SELFJOIN, true);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ String sql = "with a (x, y, z) as (select e1, e2, e3 from pm1.g1) SELECT a.x
from a, a z"; //$NON-NLS-1$
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+
+ TestOptimizer.helpPlan(sql, FakeMetadataFactory.example1Cached(), null, capFinder,
new String[] {"WITH a (x, y, z) AS (SELECT g_0.e1, g_0.e2, g_0.e3 FROM pm1.g1 AS g_0)
SELECT g_0.x FROM a AS g_0, a AS g_1"}, ComparisonMode.EXACT_COMMAND_STRING);
+ }
+
+}
Property changes on:
trunk/engine/src/test/java/org/teiid/query/processor/TestWithClauseProcessing.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2010-10-04
19:26:58 UTC (rev 2624)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2010-10-04
21:04:24 UTC (rev 2625)
@@ -3042,4 +3042,16 @@
assertEquals("A.ret",
resolvedQuery.getProjectedSymbols().get(0).getName());
}
+ @Test public void testWithDuplidateName() {
+ helpResolveException("with x as (TABLE pm1.g1), x as (TABLE pm1.g2) SELECT *
from x");
+ }
+
+ @Test public void testWithColumns() {
+ helpResolveException("with x (a, b) as (TABLE pm1.g1) SELECT * from x");
+ }
+
+ @Test public void testWithNameMatchesFrom() {
+ helpResolve("with x as (TABLE pm1.g1) SELECT * from (TABLE x) x");
+ }
+
}
\ No newline at end of file