[teiid-commits] teiid SVN: r532 - in branches/symbol_refactoring_61/engine/src: main/java/com/metamatrix/dqp/internal/datamgr/language and 31 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Tue Mar 3 12:26:44 EST 2009


Author: shawkins
Date: 2009-03-03 12:26:43 -0500 (Tue, 03 Mar 2009)
New Revision: 532

Added:
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderByItem.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Aggregate.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/DerivedColumn.java
Removed:
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AggregateSymbol.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AliasSymbol.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ExpressionSymbol.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/SingleElementSymbol.java
Modified:
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/impl/ConnectorWorkItem.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/language/LanguageBridgeFactory.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/MetaDataProcessor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/RequestWorkItem.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/GroupInfo.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/TempMetadataStore.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/AliasGenerator.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/GenerateCanonical.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/RelationalPlanner.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/plantree/NodeConstants.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CapabilitiesUtil.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleAssignOutputElements.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseAccess.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseNull.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/xml/SourceNodePlannerVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/proc/ExecDynamicSqlInstruction.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/ProjectNode.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/DynamicCommandResolver.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SimpleQueryResolver.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/XMLQueryResolver.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitorUtil.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/LanguageVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Command.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/GroupBy.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Insert.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderBy.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Query.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Select.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Update.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/navigator/PreOrPostOrderNavigator.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ElementSymbol.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/MultipleElementSymbol.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Symbol.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/SymbolMap.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/UpdateProcedureGenerator.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/AggregateSymbolCollectorVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/EvaluatableVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionSymbolCollector.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/AggregateValidationVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/UpdateValidationVisitor.java
   branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java
   branches/symbol_refactoring_61/engine/src/main/javacc/com/metamatrix/query/parser/SQLParser.jj
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/dqp/internal/datamgr/language/TestAggregateImpl.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/TestJoinWithFunction.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCapabilitiesUtil.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/parser/TestParser.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestOrderByRewrite.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestAliasSymbol.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestExpressionSymbol.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestSelect.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/symbol/TestAggregateSymbol.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestSQLStringVisitor.java
   branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestStaticSymbolMappingVisitor.java
Log:
initial commit, passing parsing

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/impl/ConnectorWorkItem.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/impl/ConnectorWorkItem.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/impl/ConnectorWorkItem.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -63,7 +63,6 @@
 import com.metamatrix.query.metadata.TempMetadataStore;
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.sql.lang.StoredProcedure;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 
 public abstract class ConnectorWorkItem extends AbstractWorkItem {
 	

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/language/LanguageBridgeFactory.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/language/LanguageBridgeFactory.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/datamgr/language/LanguageBridgeFactory.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -111,13 +111,13 @@
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
 import com.metamatrix.query.sql.lang.UnaryFromClause;
 import com.metamatrix.query.sql.lang.Update;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
@@ -209,10 +209,8 @@
             IExpression iExp = null;
             if(symbol instanceof ElementSymbol) {
                 iExp = translate((ElementSymbol)symbol);
-            } else if(symbol instanceof AggregateSymbol) {
-                iExp = translate((AggregateSymbol)symbol);
-            } else if(symbol instanceof ExpressionSymbol) {
-                iExp = translate(((ExpressionSymbol)symbol).getExpression());
+            } else if(symbol instanceof DerivedColumn) {
+                iExp = translate(((DerivedColumn)symbol).getExpression());
             }
 
             SelectSymbolImpl selectSymbol = new SelectSymbolImpl(alias, iExp);
@@ -466,7 +464,7 @@
     IExpression translate(Expression expr) throws MetaMatrixComponentException {
         if (expr == null) return null;
         if (expr instanceof CaseExpression) {
-            return translate((CaseExpression)expr);
+            throw new AssertionError("CaseExpression push down is not expected"); //$NON-NLS-1$
         } else if (expr instanceof Constant) {
             return translate((Constant)expr);
         } else if (expr instanceof Function) {
@@ -479,6 +477,8 @@
             return translate((SearchedCaseExpression)expr);
         } else if (expr instanceof SingleElementSymbol) {
             return translate((SingleElementSymbol)expr);
+        } else if (expr instanceof Aggregate) {
+        	return translate((Aggregate)expr);
         }
         return null;
     }
@@ -525,10 +525,8 @@
             return translate((AliasSymbol)symbol);
         } else if (symbol instanceof ElementSymbol) {
             return translate((ElementSymbol)symbol);
-        } else if (symbol instanceof AggregateSymbol) {
-            return translate((AggregateSymbol)symbol);
-        } else if (symbol instanceof ExpressionSymbol) {
-            return translate((ExpressionSymbol)symbol);
+        } else if (symbol instanceof DerivedColumn) {
+            return translate((DerivedColumn)symbol);
         }
         return null;
     }
@@ -553,14 +551,14 @@
         return element;
     }
 
-    IAggregate translate(AggregateSymbol symbol) throws MetaMatrixComponentException {
+    IAggregate translate(Aggregate symbol) throws MetaMatrixComponentException {
         return new AggregateImpl(symbol.getAggregateFunction(), 
                                 symbol.isDistinct(), 
                                 translate(symbol.getExpression()),
                                 symbol.getType());
     }
 
-    IExpression translate(ExpressionSymbol symbol) throws MetaMatrixComponentException {
+    IExpression translate(DerivedColumn symbol) throws MetaMatrixComponentException {
         return translate(symbol.getExpression());
     }
 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/MetaDataProcessor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/MetaDataProcessor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/MetaDataProcessor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -25,7 +25,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -57,12 +56,12 @@
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.XQuery;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 import com.metamatrix.query.sql.visitor.ReferenceCollectorVisitor;
 import com.metamatrix.query.tempdata.TempTableStore;
 
@@ -184,18 +183,14 @@
             this.metadata = tempFacade; 
         }
         
-        List projectedSymbols = originalCommand.getProjectedSymbols();
+        List<DerivedColumn> projectedSymbols = originalCommand.getProjectedSymbols();
         columnMetadata = new Map[projectedSymbols.size()];
         
-        Iterator symbolIter = projectedSymbols.iterator();
-        for(int i=0; symbolIter.hasNext(); i++) {
-            SingleElementSymbol symbol = (SingleElementSymbol) symbolIter.next();
-            String shortColumnName = SingleElementSymbol.getShortName(symbol.getOutputName());
-            if(symbol instanceof AliasSymbol) {
-                symbol = ((AliasSymbol)symbol).getSymbol();
-            }
+        for (int i = 0; i < projectedSymbols.size(); i++) {
+        	DerivedColumn symbol = projectedSymbols.get(i);
+            String shortColumnName = Symbol.getShortName(symbol.getOutputName());
             try {
-                columnMetadata[i] = createColumnMetadata(shortColumnName, symbol);
+                columnMetadata[i] = createColumnMetadata(shortColumnName, symbol.getExpression());
             } catch(QueryMetadataException e) {
                 throw new MetaMatrixComponentException(e);
             }
@@ -239,11 +234,11 @@
         return xqueryMetadata;
     }
 
-    private Map createColumnMetadata(String shortColumnName, SingleElementSymbol symbol) throws QueryMetadataException, MetaMatrixComponentException {
+    private Map createColumnMetadata(String shortColumnName, Expression symbol) throws QueryMetadataException, MetaMatrixComponentException {
         if(symbol instanceof ElementSymbol) {
             return createElementMetadata(shortColumnName, (ElementSymbol) symbol);        
-        } else if(symbol instanceof AggregateSymbol) {
-            return createAggregateMetadata(shortColumnName, (AggregateSymbol) symbol);
+        } else if (symbol instanceof Aggregate) {
+    		return createAggregateMetadata(shortColumnName, (Aggregate) symbol);
         }
         return createTypedMetadata(shortColumnName, symbol);            
     }
@@ -315,19 +310,19 @@
     }
     
     private Map createAggregateMetadata(String shortColumnName,
-                                        AggregateSymbol symbol) throws QueryMetadataException, MetaMatrixComponentException {
+                                        Aggregate symbol) throws QueryMetadataException, MetaMatrixComponentException {
         
         Expression expression = symbol.getExpression();
         String function = symbol.getAggregateFunction();
         if(function.equals(ReservedWords.MIN) || function.equals(ReservedWords.MAX)){
             if(expression instanceof ElementSymbol) {
-                return createColumnMetadata(shortColumnName, (ElementSymbol)expression);
+                return createColumnMetadata(shortColumnName, expression);
             }
         }
         return createTypedMetadata(shortColumnName, symbol);
     }
 
-    private Map createTypedMetadata(String shortColumnName, SingleElementSymbol symbol) {
+    private Map createTypedMetadata(String shortColumnName, Expression symbol) {
         return getDefaultColumn(vdbName, vdbVersion, null, shortColumnName, symbol.getType());
     }
     

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/RequestWorkItem.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/RequestWorkItem.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/dqp/internal/process/RequestWorkItem.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -82,6 +82,7 @@
 import com.metamatrix.query.sql.lang.SPParameter;
 import com.metamatrix.query.sql.lang.StoredProcedure;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 
 public class RequestWorkItem extends AbstractWorkItem {
 	
@@ -501,7 +502,7 @@
 
         for(int i=0; i<columnSymbols.size(); i++) {
             SingleElementSymbol symbol = (SingleElementSymbol) columnSymbols.get(i);
-            columnNames[i] = SingleElementSymbol.getShortName(symbol.getOutputName());
+            columnNames[i] = Symbol.getShortName(symbol.getOutputName());
             dataTypes[i] = DataTypeManager.getDataTypeName(symbol.getType());
         }
         

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -55,16 +55,15 @@
 import com.metamatrix.query.sql.lang.MatchCriteria;
 import com.metamatrix.query.sql.lang.NotCriteria;
 import com.metamatrix.query.sql.lang.SubqueryCompareCriteria;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
 import com.metamatrix.query.sql.symbol.SearchedCaseExpression;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.util.ValueIterator;
 import com.metamatrix.query.util.CommandContext;
 import com.metamatrix.query.util.ErrorMessageKeys;
@@ -491,8 +490,8 @@
 	           return tuple.get(index.intValue());
 	       }
 	       // Otherwise this should be an ExpressionSymbol and we just need to dive in and evaluate the expression itself
-	       if (expression instanceof ExpressionSymbol && !(expression instanceof AggregateSymbol)) {            
-	           ExpressionSymbol exprSyb = (ExpressionSymbol) expression;
+	       if (expression instanceof DerivedColumn && !(expression instanceof Aggregate)) {            
+	           DerivedColumn exprSyb = (DerivedColumn) expression;
 	           Expression expr = exprSyb.getExpression();
 	           return internalEvaluate(expr, tuple);
 	       } 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/GroupInfo.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/GroupInfo.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/GroupInfo.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -44,7 +44,7 @@
 	
 	public GroupInfo(LinkedHashMap<Object, ElementSymbol> symbols) {
 		this.idToSymbolMap = symbols;
-		this.symbolList = Collections.unmodifiableList(new ArrayList(symbols.values()));
+		this.symbolList = Collections.unmodifiableList(new ArrayList<ElementSymbol>(symbols.values()));
 		this.shortNameToSymbolMap = new HashMap<String, ElementSymbol>(symbolList.size());
 		for (ElementSymbol symbol : symbolList) {
 			shortNameToSymbolMap.put(symbol.getShortCanonicalName(), symbol);

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/TempMetadataStore.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/TempMetadataStore.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/metadata/TempMetadataStore.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -29,13 +29,11 @@
 import java.util.List;
 import java.util.Map;
 
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 
 /**
  * Store for temporary metadata discovering while resolving a query.
@@ -101,13 +99,13 @@
      * @param isVirtual whether or not the group is a virtual group
      * @param isTempTable whether or not the group is a temporary table
      */
-    public TempMetadataID addTempGroup(String tempGroup, List<? extends SingleElementSymbol> tempSymbols, boolean isVirtual, boolean isTempTable) { 
+    public TempMetadataID addTempGroup(String tempGroup, List<DerivedColumn> tempSymbols, boolean isVirtual, boolean isTempTable) { 
         // Add the temporary group
         String tempName = tempGroup.toUpperCase();
         
         List elementIDs = new ArrayList(tempSymbols.size());
         
-        for (SingleElementSymbol symbol : tempSymbols) {
+        for (DerivedColumn symbol : tempSymbols) {
             TempMetadataID elementID = createElementSymbol(tempName, symbol, isTempTable);
         
             elementIDs.add(elementID);
@@ -119,30 +117,20 @@
         return groupID;
     }
 
-    private TempMetadataID createElementSymbol(String tempName, SingleElementSymbol symbol, boolean isTempTable) {
+    private TempMetadataID createElementSymbol(String tempName, DerivedColumn symbol, boolean isTempTable) {
         // Create new element name
-        String elementName = tempName + SingleElementSymbol.SEPARATOR + symbol.getShortCanonicalName();
+        String elementName = tempName + Symbol.SEPARATOR + symbol.getShortCanonicalName();
         
         Object metadataID = null;
         
-        if (symbol instanceof AliasSymbol) {
-            AliasSymbol as = (AliasSymbol)symbol;
-            symbol = as.getSymbol();
-        }
-        
         //the following allows for orginal metadata ids to be determined for proc inputs
-        if (symbol instanceof ExpressionSymbol && !(symbol instanceof AggregateSymbol)) {
-            Expression expr = ((ExpressionSymbol)symbol).getExpression();
-            if (expr instanceof Reference) {
-                expr = ((Reference)expr).getExpression();
-            } 
-            if (expr instanceof ElementSymbol) {
-                symbol = (ElementSymbol)expr;
-            }
-        }
+        Expression expr = symbol.getExpression();
+        if (expr instanceof Reference) {
+            expr = ((Reference)expr).getExpression();
+        } 
         
-        if (symbol instanceof ElementSymbol) {
-            metadataID = ((ElementSymbol)symbol).getMetadataID();
+        if (expr instanceof ElementSymbol) {
+            metadataID = ((ElementSymbol)expr).getMetadataID();
         }
         
         while (metadataID != null && metadataID instanceof TempMetadataID) {
@@ -161,7 +149,7 @@
      * @param symbol - element to be added
      * @return metadata id.
      */
-    public TempMetadataID addElementSymbolToTempGroup(String tempGroup, SingleElementSymbol symbol) {
+    public TempMetadataID addElementSymbolToTempGroup(String tempGroup, DerivedColumn symbol) {
         String tempName = tempGroup.toUpperCase();
         
         TempMetadataID groupID = (TempMetadataID)this.tempGroups.get(tempName);
@@ -207,7 +195,7 @@
      * @return Metadata ID or null if not found
      */
     public TempMetadataID getTempElementID(String tempElement) {
-        int index = tempElement.lastIndexOf(SingleElementSymbol.SEPARATOR);
+        int index = tempElement.lastIndexOf(Symbol.SEPARATOR);
         if(index < 0) {
             return null;
         }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/AliasGenerator.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/AliasGenerator.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/AliasGenerator.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -39,14 +39,13 @@
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
 import com.metamatrix.query.sql.lang.UnaryFromClause;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 import com.metamatrix.query.sql.util.SymbolMap;
 
 /**
@@ -66,7 +65,7 @@
             
             Map<String, Map<String, String>> elementMap = new HashMap<String, Map<String, String>>();
             Map<String, String> groupNames = new HashMap<String, String>();
-            Map<SingleElementSymbol, String> currentSymbols;
+            Map<DerivedColumn, String> currentSymbols;
             
             boolean aliasColumns = false;
             
@@ -74,27 +73,23 @@
                 this.parent = parent;
             }
             
-            public String getElementName(SingleElementSymbol symbol, boolean renameGroup) {
+            public String getElementName(ElementSymbol symbol, boolean renameGroup) {
             	String name = null;
             	if (currentSymbols != null) {
             		name = currentSymbols.get(symbol);
                 	if (name != null) {
-                		if (renameGroup && symbol instanceof ElementSymbol) {
-            				renameGroup(((ElementSymbol)symbol).getGroupSymbol());
+                		if (renameGroup) {
+            				renameGroup(symbol.getGroupSymbol());
             			}
                 		return name;
                 	}
             	}
-            	if (!(symbol instanceof ElementSymbol)) {
-            		return null;
-            	}
-            	ElementSymbol element = (ElementSymbol)symbol;
-            	Map<String, String> elements = this.elementMap.get(element.getGroupSymbol().getCanonicalName());
+            	Map<String, String> elements = this.elementMap.get(symbol.getGroupSymbol().getCanonicalName());
             	if (elements != null) {
-            		name = elements.get(element.getShortCanonicalName());
+            		name = elements.get(symbol.getShortCanonicalName());
             		if (name != null) {
             			if (renameGroup) {
-            				renameGroup(element.getGroupSymbol());
+            				renameGroup(symbol.getGroupSymbol());
             			}
             			return name;
             		}
@@ -106,7 +101,7 @@
                 	}
                 }
             	if (renameGroup) {
-    				renameGroup(element.getGroupSymbol());
+    				renameGroup(symbol.getGroupSymbol());
     			}
             	return null;
             }
@@ -221,7 +216,7 @@
             SingleElementSymbol newSymbol = symbol;
             
             if (!(expr instanceof SingleElementSymbol)) {
-                newSymbol = new ExpressionSymbol(newSymbol.getShortName(), expr);
+                newSymbol = new DerivedColumn(newSymbol.getShortName(), expr);
             } else if (expr instanceof ElementSymbol) {
                 if (!needsAlias(newAlias, (ElementSymbol)expr)) {
                     needsAlias = false;
@@ -335,7 +330,7 @@
             Expression expr = SymbolMap.getExpression(element);
                         
             if (!(expr instanceof SingleElementSymbol)) {
-                expr = new ExpressionSymbol(element.getShortName(), expr);
+                expr = new DerivedColumn(element.getShortName(), expr);
             } else if (expr instanceof ElementSymbol) {
                 needsAlias = needsAlias(name, (ElementSymbol)expr);
             } 
@@ -353,7 +348,7 @@
         for (int i = 0; i < obj.getVariableCount(); i++) {
         	SingleElementSymbol element = obj.getVariable(i);
         	if (element instanceof ElementSymbol) {
-        		element.setOutputName(SingleElementSymbol.getShortName(element.getOutputName()));
+        		element.setOutputName(Symbol.getShortName(element.getOutputName()));
         	}
         }
     }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/GenerateCanonical.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/GenerateCanonical.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/GenerateCanonical.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -442,8 +442,7 @@
 	private static PlanNode attachSorting(PlanNode plan, OrderBy orderBy) {
 		PlanNode sortNode = NodeFactory.getNewNode(NodeConstants.Types.SORT);
 		
-		sortNode.setProperty(NodeConstants.Info.SORT_ORDER, orderBy.getVariables());
-		sortNode.setProperty(NodeConstants.Info.ORDER_TYPES, orderBy.getTypes());
+		sortNode.setProperty(NodeConstants.Info.SORT_ORDER, orderBy.getSortOrder());
 
 		sortNode.addGroups(GroupsUsedByElementsVisitor.getGroups(orderBy));
 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -73,6 +73,7 @@
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.sql.lang.Criteria;
 import com.metamatrix.query.sql.lang.JoinType;
+import com.metamatrix.query.sql.lang.OrderByItem;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.StoredProcedure;
 import com.metamatrix.query.sql.lang.SetQuery.Operation;
@@ -356,10 +357,9 @@
 			case NodeConstants.Types.SORT:
                 SortNode sortNode = new SortNode(getID());
                 
-				List elements = (List) node.getProperty(NodeConstants.Info.SORT_ORDER);
-				List sortTypes = (List) node.getProperty(NodeConstants.Info.ORDER_TYPES);
+				List<OrderByItem> elements = (List<OrderByItem>) node.getProperty(NodeConstants.Info.SORT_ORDER);
 				
-				sortNode.setSortElements(elements, sortTypes);
+				sortNode.setSortElements(elements);
 
 				processNode = sortNode;
 				break;

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/RelationalPlanner.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/RelationalPlanner.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -52,9 +52,9 @@
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.sql.lang.Criteria;
 import com.metamatrix.query.sql.lang.SubqueryContainer;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.visitor.CorrelatedReferenceCollectorVisitor;
 import com.metamatrix.query.sql.visitor.GroupCollectorVisitor;
 import com.metamatrix.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
@@ -129,12 +129,10 @@
         }
         
         // Set top column information on top node
-        List projectCols = command.getProjectedSymbols();
-        List<SingleElementSymbol> topCols = new ArrayList<SingleElementSymbol>(projectCols.size());
-        Iterator projectIter = projectCols.iterator();
-        while(projectIter.hasNext()) {
-            SingleElementSymbol symbol = (SingleElementSymbol) projectIter.next();
-            topCols.add( (SingleElementSymbol)symbol.clone() );
+        List<DerivedColumn> projectCols = command.getProjectedSymbols();
+        List<DerivedColumn> topCols = new ArrayList<DerivedColumn>(projectCols.size());
+        for (DerivedColumn derivedColumn : projectCols) {
+            topCols.add( (DerivedColumn)derivedColumn.clone() );
         }
 
         // Build rule set based on hints

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/plantree/NodeConstants.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/plantree/NodeConstants.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -108,7 +108,6 @@
         IS_DEPENDENT_SET, // Boolean - only used with dependent joins
 
         // Sort node properties
-        ORDER_TYPES,        // List <Boolean>
         SORT_ORDER,         // List <SingleElementSymbol>
         SORT_CONTROLLER,         // Boolean
 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CapabilitiesUtil.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CapabilitiesUtil.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -38,7 +38,7 @@
 import com.metamatrix.query.sql.lang.Criteria;
 import com.metamatrix.query.sql.lang.JoinType;
 import com.metamatrix.query.sql.lang.SetQuery.Operation;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
@@ -157,7 +157,7 @@
         return true;
     }
 
-    public static boolean supportsAggregateFunction(Object modelID, AggregateSymbol aggregate, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) 
+    public static boolean supportsAggregateFunction(Object modelID, Aggregate aggregate, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) 
     throws QueryMetadataException, MetaMatrixComponentException {
         
         if (metadata.isVirtualModel(modelID)){

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -48,7 +48,7 @@
 import com.metamatrix.query.sql.lang.SubqueryCompareCriteria;
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Function;
@@ -99,7 +99,7 @@
         }          
     }
     
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         if(this.caps == null) {
             return;
         }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -54,15 +54,13 @@
 import com.metamatrix.query.sql.lang.StoredProcedure;
 import com.metamatrix.query.sql.navigator.PostOrderNavigator;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.util.SymbolMap;
 import com.metamatrix.query.sql.visitor.ElementCollectorVisitor;
 import com.metamatrix.query.sql.visitor.ExpressionMappingVisitor;
@@ -295,13 +293,13 @@
         SingleElementSymbol mappedSymbol = null;
         
         if(!(mappedExpression instanceof SingleElementSymbol)) { 
-            mappedSymbol = new ExpressionSymbol(name, mappedExpression);
+            mappedSymbol = new DerivedColumn(name, mappedExpression);
         } else {
             mappedSymbol = (SingleElementSymbol)mappedExpression;
         }
         
         // Re-alias to maintain name if necessary
-        if(shouldAlias && (mappedSymbol instanceof ExpressionSymbol || !mappedSymbol.getShortCanonicalName().equals(name.toUpperCase()))) { 
+        if(shouldAlias && (mappedSymbol instanceof DerivedColumn || !mappedSymbol.getShortCanonicalName().equals(name.toUpperCase()))) { 
             mappedSymbol = new AliasSymbol(name, mappedSymbol);
         }   
         
@@ -322,8 +320,8 @@
             return expression;
         }
         
-        if(expression instanceof AggregateSymbol) {
-            AggregateSymbol aggSymbol = (AggregateSymbol) expression;
+        if(expression instanceof Aggregate) {
+            Aggregate aggSymbol = (Aggregate) expression;
             
             // First try to replace the entire aggregate
             SingleElementSymbol replacement = (SingleElementSymbol) symbolMap.get(aggSymbol);

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleAssignOutputElements.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleAssignOutputElements.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleAssignOutputElements.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -48,11 +48,11 @@
 import com.metamatrix.query.sql.lang.Criteria;
 import com.metamatrix.query.sql.lang.StoredProcedure;
 import com.metamatrix.query.sql.lang.SetQuery.Operation;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
@@ -373,8 +373,8 @@
                         ss = ((AliasSymbol)ss).getSymbol();
                     }
                     
-                    if (ss instanceof ExpressionSymbol && !(ss instanceof AggregateSymbol)) {
-                        ExpressionSymbol exprSymbol = (ExpressionSymbol)ss;
+                    if (ss instanceof DerivedColumn) {
+                        DerivedColumn exprSymbol = (DerivedColumn)ss;
                         
                         if (!exprSymbol.isDerivedExpression()) {
                             createdSymbols.add(ss);
@@ -402,10 +402,10 @@
 				List<SingleElementSymbol> groupCols = (List<SingleElementSymbol>) node.getProperty(NodeConstants.Info.GROUP_COLS);
 				if(groupCols != null) {
 				    for (SingleElementSymbol expression : groupCols) {
-                        if(expression instanceof ElementSymbol || expression instanceof AggregateSymbol) {
+                        if(expression instanceof ElementSymbol || expression instanceof Aggregate) {
                             requiredSymbols.add(expression);
                         } else {    
-                            ExpressionSymbol exprSymbol = (ExpressionSymbol) expression;
+                            DerivedColumn exprSymbol = (DerivedColumn) expression;
                             Expression expr = exprSymbol.getExpression();
                             AggregateSymbolCollectorVisitor.getAggregates(expr, requiredSymbols, requiredSymbols);
                             createdSymbols.add(exprSymbol);
@@ -415,8 +415,8 @@
 
 				// Take credit for creating any aggregates that are needed above
 				for (SingleElementSymbol outputSymbol : outputCols) {
-					if(outputSymbol instanceof AggregateSymbol) {
-					    AggregateSymbol agg = (AggregateSymbol)outputSymbol;
+					if(outputSymbol instanceof Aggregate) {
+					    Aggregate agg = (Aggregate)outputSymbol;
 					    createdSymbols.add(outputSymbol);
 					    
 	                    Expression aggExpr = agg.getExpression();

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -44,7 +44,7 @@
 import com.metamatrix.query.sql.lang.Criteria;
 import com.metamatrix.query.sql.lang.JoinType;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.visitor.GroupsUsedByElementsVisitor;
@@ -151,16 +151,16 @@
     private static AtomicInteger EXPRESSION_INDEX = new AtomicInteger(0);
     
     private static List<SingleElementSymbol> createExpressionSymbols(List<Expression> expressions) {
-        HashMap<Expression, ExpressionSymbol> uniqueExpressions = new HashMap<Expression, ExpressionSymbol>();
+        HashMap<Expression, DerivedColumn> uniqueExpressions = new HashMap<Expression, DerivedColumn>();
         List<SingleElementSymbol> result = new ArrayList<SingleElementSymbol>();
         for (Expression expression : expressions) {
             if (expression instanceof SingleElementSymbol) {
                 result.add((SingleElementSymbol)expression);
                 continue;
             } 
-            ExpressionSymbol expressionSymbol = uniqueExpressions.get(expression);
+            DerivedColumn expressionSymbol = uniqueExpressions.get(expression);
             if (expressionSymbol == null) {
-                expressionSymbol = new ExpressionSymbol("$" + EXPRESSION_INDEX.getAndIncrement(), expression); //$NON-NLS-1$
+                expressionSymbol = new DerivedColumn("$" + EXPRESSION_INDEX.getAndIncrement(), expression); //$NON-NLS-1$
                 expressionSymbol.setDerivedExpression(true);
                 uniqueExpressions.put(expression, expressionSymbol);
             }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -57,7 +57,7 @@
 import com.metamatrix.query.sql.lang.JoinType;
 import com.metamatrix.query.sql.lang.OrderBy;
 import com.metamatrix.query.sql.lang.Select;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
@@ -101,7 +101,7 @@
             }
 
             List<SingleElementSymbol> groupingExpressions = (List<SingleElementSymbol>)groupNode.getProperty(NodeConstants.Info.GROUP_COLS);
-            Set<AggregateSymbol> aggregates = collectAggregates(groupNode);
+            Set<Aggregate> aggregates = collectAggregates(groupNode);
 
             pushGroupNode(groupNode, groupingExpressions, aggregates, metadata, capFinder);
         }
@@ -117,8 +117,8 @@
      * @return the set of aggregate symbols found
      * @since 4.2
      */
-    static Set<AggregateSymbol> collectAggregates(PlanNode groupNode) {
-        Set<AggregateSymbol> aggregates = new HashSet<AggregateSymbol>();
+    static Set<Aggregate> collectAggregates(PlanNode groupNode) {
+        Set<Aggregate> aggregates = new HashSet<Aggregate>();
         PlanNode currentNode = groupNode.getParent();
         while (currentNode != null) {
             if (currentNode.getType() == NodeConstants.Types.PROJECT) {
@@ -146,7 +146,7 @@
      */
     private void pushGroupNode(PlanNode groupNode,
                                List<SingleElementSymbol> groupingExpressions,
-                               Set<AggregateSymbol> allAggregates,
+                               Set<Aggregate> allAggregates,
                                QueryMetadataInterface metadata,
                                CapabilitiesFinder capFinder) throws MetaMatrixComponentException,
                                                             QueryMetadataException {
@@ -198,7 +198,7 @@
             } else {
                 // if the source has no rows we need to insert a select node with criteria count(*)>0
                 PlanNode selectNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT);
-                AggregateSymbol count = new AggregateSymbol("stagedAgg", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+                Aggregate count = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
                 aggregates.add(count); //consider the count aggregate for the push down call below
                 selectNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, new CompareCriteria(count, CompareCriteria.GT,
                                                                                                new Constant(new Integer(0))));
@@ -228,7 +228,7 @@
         }
         
         for (final Iterator<SingleElementSymbol> iterator = aggregates.iterator(); iterator.hasNext();) {
-            final AggregateSymbol symbol = (AggregateSymbol)iterator.next();
+            final Aggregate symbol = (Aggregate)iterator.next();
             Expression expr = symbol.getExpression();
             if (expr == null) {
                 continue;
@@ -241,8 +241,8 @@
         if (!aggregates.isEmpty()) {
             // Fix any aggregate expressions so they correctly recombine the staged aggregates
             try {
-                Set<AggregateSymbol> newAggs = new HashSet<AggregateSymbol>();
-                Map<AggregateSymbol, Expression> aggMap = buildAggregateMap(aggregates, metadata, newAggs);
+                Set<Aggregate> newAggs = new HashSet<Aggregate>();
+                Map<Aggregate, Expression> aggMap = buildAggregateMap(aggregates, metadata, newAggs);
                 mapExpressions(groupNode.getParent(), aggMap);
                 aggregates.clear();
                 aggregates.addAll(newAggs);
@@ -252,18 +252,18 @@
         } 
     }
     
-    private void collectSymbolsFromOtherAggregates(Collection<AggregateSymbol> allAggregates,
+    private void collectSymbolsFromOtherAggregates(Collection<Aggregate> allAggregates,
                                                       Collection<SingleElementSymbol> aggregates,
                                                       PlanNode current,
                                                       Set<SingleElementSymbol> stagedGroupingSymbols) {
-        Set<AggregateSymbol> otherAggs = new HashSet<AggregateSymbol>(allAggregates);
+        Set<Aggregate> otherAggs = new HashSet<Aggregate>(allAggregates);
         if (aggregates != null) {
             otherAggs.removeAll(aggregates);
         }
 
         PlanNode source = FrameUtil.findJoinSourceNode(current);
 
-        for (AggregateSymbol aggregateSymbol : otherAggs) {
+        for (Aggregate aggregateSymbol : otherAggs) {
             for (ElementSymbol symbol : ElementCollectorVisitor.getElements(aggregateSymbol, true)) {
                 if (source.getGroups().contains(symbol.getGroupSymbol())) {
                     stagedGroupingSymbols.add(symbol);
@@ -326,8 +326,8 @@
             return result;
         }
         for (SingleElementSymbol aggregateSymbol : expressions) {
-            if (aggregateSymbol instanceof AggregateSymbol) {
-                AggregateSymbol partitionAgg = (AggregateSymbol)aggregateSymbol;
+            if (aggregateSymbol instanceof Aggregate) {
+                Aggregate partitionAgg = (Aggregate)aggregateSymbol;
                 if (partitionAgg.isDistinct()) {
                     continue; //currently we cann't consider distinct aggs
                 }
@@ -365,19 +365,19 @@
         return result;
     }
 
-    private Map<AggregateSymbol, Expression> buildAggregateMap(Collection<SingleElementSymbol> aggregateExpressions,
-                                                                        QueryMetadataInterface metadata, Set<AggregateSymbol> nestedAggregates) throws QueryResolverException,
+    private Map<Aggregate, Expression> buildAggregateMap(Collection<SingleElementSymbol> aggregateExpressions,
+                                                                        QueryMetadataInterface metadata, Set<Aggregate> nestedAggregates) throws QueryResolverException,
                                                                                                         MetaMatrixComponentException {
-        Map<AggregateSymbol, Expression> aggMap = new HashMap<AggregateSymbol, Expression>();
+        Map<Aggregate, Expression> aggMap = new HashMap<Aggregate, Expression>();
         for (SingleElementSymbol symbol : aggregateExpressions) {
-            AggregateSymbol partitionAgg = (AggregateSymbol)symbol;
+            Aggregate partitionAgg = (Aggregate)symbol;
            
             Expression newExpression = null;
 
             String aggFunction = partitionAgg.getAggregateFunction();
             if (aggFunction.equals(ReservedWords.COUNT)) {
                 //COUNT(x) -> CONVERT(SUM(COUNT(x)), INTEGER)
-                AggregateSymbol newAgg = new AggregateSymbol("stagedAgg", ReservedWords.SUM, false, partitionAgg); //$NON-NLS-1$
+                Aggregate newAgg = new Aggregate(ReservedWords.SUM, false, partitionAgg); //$NON-NLS-1$
 
                 // Build conversion function to convert SUM (which returns LONG) back to INTEGER
                 Constant convertTargetType = new Constant(DataTypeManager.getDataTypeName(partitionAgg.getType()),
@@ -391,11 +391,11 @@
                 nestedAggregates.add(partitionAgg);
             } else if (aggFunction.equals(ReservedWords.AVG)) {
                 //AVG(x) -> SUM(SUM(x)) / SUM(COUNT(x))
-                AggregateSymbol countAgg = new AggregateSymbol("stagedAgg", ReservedWords.COUNT, false, partitionAgg.getExpression()); //$NON-NLS-1$
-                AggregateSymbol sumAgg = new AggregateSymbol("stagedAgg", ReservedWords.SUM, false, partitionAgg.getExpression()); //$NON-NLS-1$
+                Aggregate countAgg = new Aggregate(ReservedWords.COUNT, false, partitionAgg.getExpression()); //$NON-NLS-1$
+                Aggregate sumAgg = new Aggregate(ReservedWords.SUM, false, partitionAgg.getExpression()); //$NON-NLS-1$
                 
-                AggregateSymbol sumSumAgg = new AggregateSymbol("stagedAgg", ReservedWords.SUM, false, sumAgg); //$NON-NLS-1$
-                AggregateSymbol sumCountAgg = new AggregateSymbol("stagedAgg", ReservedWords.SUM, false, countAgg); //$NON-NLS-1$
+                Aggregate sumSumAgg = new Aggregate(ReservedWords.SUM, false, sumAgg); //$NON-NLS-1$
+                Aggregate sumCountAgg = new Aggregate(ReservedWords.SUM, false, countAgg); //$NON-NLS-1$
 
                 Function divideFunc = new Function("/", new Expression[] {sumSumAgg, sumCountAgg}); //$NON-NLS-1$
                 ResolverVisitorUtil.resolveFunction(divideFunc, metadata);
@@ -405,7 +405,7 @@
                 nestedAggregates.add(sumAgg);
             } else {
                 //AGG(X) -> AGG(AGG(X))
-                newExpression = new AggregateSymbol("stagedAgg", aggFunction, false, partitionAgg); //$NON-NLS-1$
+                newExpression = new Aggregate(aggFunction, false, partitionAgg); //$NON-NLS-1$
                 nestedAggregates.add(partitionAgg);
             }
 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseAccess.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseAccess.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseAccess.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -51,7 +51,7 @@
 import com.metamatrix.query.sql.lang.JoinType;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.SetQuery.Operation;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
@@ -146,7 +146,7 @@
             }            
             case NodeConstants.Types.GROUP:            
             {                
-                Set<AggregateSymbol> aggregates = RulePushAggregates.collectAggregates(parentNode);
+                Set<Aggregate> aggregates = RulePushAggregates.collectAggregates(parentNode);
                 if (canRaiseOverGroupBy(parentNode, accessNode, aggregates, metadata, capFinder)) {
                     return performRaise(rootNode, accessNode, parentNode);
                 }
@@ -216,7 +216,7 @@
 
     static boolean canRaiseOverGroupBy(PlanNode groupNode,
                                          PlanNode accessNode,
-                                         Collection<? extends SingleElementSymbol> aggregates,
+                                         Set<Aggregate> aggregates,
                                          QueryMetadataInterface metadata,
                                          CapabilitiesFinder capFinder) throws QueryMetadataException,
                                                         MetaMatrixComponentException {
@@ -236,7 +236,7 @@
             }
         }
         if (aggregates != null) {
-            for (SingleElementSymbol aggregateSymbol : aggregates) {
+            for (Aggregate aggregateSymbol : aggregates) {
                 if(! CriteriaCapabilityValidatorVisitor.canPushLanguageObject(aggregateSymbol, modelID, metadata, capFinder)) {
                     return false;
                 }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseNull.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseNull.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRaiseNull.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -42,7 +42,7 @@
 import com.metamatrix.query.sql.lang.JoinType;
 import com.metamatrix.query.sql.lang.SetQuery;
 import com.metamatrix.query.sql.symbol.AliasSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.util.SymbolMap;
@@ -148,7 +148,7 @@
                     for (int i = 0; i < newProjectSymbols.size(); i++) {
                         SingleElementSymbol newSes = newProjectSymbols.get(i);
                         SingleElementSymbol oldSes = oldProjectSymbols.get(i);
-                        if (newSes instanceof ExpressionSymbol || !newSes.getShortCanonicalName().equals(oldSes.getShortCanonicalName())) {
+                        if (newSes instanceof DerivedColumn || !newSes.getShortCanonicalName().equals(oldSes.getShortCanonicalName())) {
                             if (newSes instanceof AliasSymbol) {
                                 newSes = ((AliasSymbol)newSes).getSymbol();
                             }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -47,7 +47,7 @@
 import com.metamatrix.query.sql.ReservedWords;
 import com.metamatrix.query.sql.lang.Criteria;
 import com.metamatrix.query.sql.lang.JoinType;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
@@ -267,8 +267,8 @@
 					break;
 				}
 				case NodeConstants.Types.GROUP: {
-					Set<AggregateSymbol> aggs = RulePushAggregates.collectAggregates(parent);
-					for (AggregateSymbol aggregateSymbol : aggs) {
+					Set<Aggregate> aggs = RulePushAggregates.collectAggregates(parent);
+					for (Aggregate aggregateSymbol : aggs) {
 						if (aggregateSymbol.getAggregateFunction().equalsIgnoreCase(ReservedWords.COUNT) || 
 								aggregateSymbol.getAggregateFunction().equalsIgnoreCase(ReservedWords.AVG)) {
 							return false;

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/xml/SourceNodePlannerVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/xml/SourceNodePlannerVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/optimizer/xml/SourceNodePlannerVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -53,6 +53,7 @@
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 import com.metamatrix.query.sql.visitor.ElementCollectorVisitor;
 import com.metamatrix.query.sql.visitor.ExpressionMappingVisitor;
 import com.metamatrix.query.sql.visitor.ReferenceCollectorVisitor;
@@ -112,7 +113,7 @@
             baseQuery.getSelect().clearSymbols();
             for (Iterator i = ResolverUtil.resolveElementsInGroup(groupSymbol, planEnv.getGlobalMetadata()).iterator(); i.hasNext();) {
                 SingleElementSymbol ses = (SingleElementSymbol)i.next();
-                baseQuery.getSelect().addSymbol(new ElementSymbol(newGroup + SingleElementSymbol.SEPARATOR + ses.getShortName()));
+                baseQuery.getSelect().addSymbol(new ElementSymbol(newGroup + Symbol.SEPARATOR + ses.getShortName()));
             }
             
             rsInfo.setCommand(baseQuery);

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/proc/ExecDynamicSqlInstruction.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/proc/ExecDynamicSqlInstruction.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/proc/ExecDynamicSqlInstruction.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -73,9 +73,10 @@
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 import com.metamatrix.query.sql.util.VariableContext;
 import com.metamatrix.query.sql.visitor.GroupCollectorVisitor;
 import com.metamatrix.query.sql.visitor.ReferenceCollectorVisitor;
@@ -318,13 +319,13 @@
 			}
 			SingleElementSymbol wrappedSymbol = new ElementSymbol(groupSymbol
 					.getCanonicalName()
-					+ SingleElementSymbol.SEPARATOR
+					+ Symbol.SEPARATOR
 					+ actualName);
 
             Expression result = ResolverUtil.convertExpression(wrappedSymbol, DataTypeManager.getDataTypeName(projectedSymbolType), DataTypeManager.getDataTypeName(expectedSymbol.getType()));
             
 			if (!(result instanceof SingleElementSymbol)) {
-				wrappedSymbol = new ExpressionSymbol(expectedName, result);
+				wrappedSymbol = new DerivedColumn(expectedName, result);
 				shouldAlias = true;
 			}
 			if (shouldAlias) {

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -49,7 +49,7 @@
 import com.metamatrix.query.function.aggregate.Sum;
 import com.metamatrix.query.sql.ReservedWords;
 import com.metamatrix.query.sql.lang.OrderBy;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.util.TypeRetrievalUtil;
@@ -168,8 +168,8 @@
         Iterator outputIter = getElements().iterator();
         while(outputIter.hasNext()) {
             Object outputSymbol = outputIter.next();
-            if(outputSymbol instanceof AggregateSymbol) {
-                AggregateSymbol agg = (AggregateSymbol) outputSymbol;
+            if(outputSymbol instanceof Aggregate) {
+                Aggregate agg = (Aggregate) outputSymbol;
                 Expression expr = agg.getExpression();
                 if(expr != null && ! this.collectedExpressions.contains(expr)) {
                     this.collectedExpressions.add(expr);
@@ -186,8 +186,8 @@
         functions = new AggregateFunction[getElements().size()];
         for(int i=0; i<getElements().size(); i++) {
             Object symbol = getElements().get(i);
-            if(symbol instanceof AggregateSymbol) {
-                AggregateSymbol aggSymbol = (AggregateSymbol) symbol;
+            if(symbol instanceof Aggregate) {
+                Aggregate aggSymbol = (Aggregate) symbol;
 
                 if(aggSymbol.getExpression() == null) {
                     functions[i] = new Count();
@@ -406,8 +406,8 @@
 
         for(int i=0; i<functions.length; i++) {
             Expression expression = (SingleElementSymbol) getElements().get(i);
-            if(expression instanceof AggregateSymbol) {
-                expression = ((AggregateSymbol)expression).getExpression();
+            if(expression instanceof Aggregate) {
+                expression = ((Aggregate)expression).getExpression();
             }
 
             Object value = null;

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/ProjectNode.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/ProjectNode.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/ProjectNode.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -36,11 +36,11 @@
 import com.metamatrix.core.util.Assertion;
 import com.metamatrix.query.eval.Evaluator;
 import com.metamatrix.query.execution.QueryExecPlugin;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.SelectSymbol;
 import com.metamatrix.query.util.ErrorMessageKeys;
 
@@ -125,7 +125,7 @@
                             symbol = ((AliasSymbol)symbol).getSymbol();
                         }
     
-                        if(symbol instanceof ElementSymbol || symbol instanceof AggregateSymbol) {
+                        if(symbol instanceof ElementSymbol || symbol instanceof Aggregate) {
                             Integer index = (Integer) elementMap.get(symbol);
                             if(index == null || index.intValue() != i) {
                                 // input / output element order is not the same
@@ -266,8 +266,8 @@
         Integer index = (Integer) elementMap.get(symbol);
         if(index != null) {
 			tuple.add(values.get(index.intValue()));
-        } else if(symbol instanceof ExpressionSymbol) {
-            Expression expression = ((ExpressionSymbol)symbol).getExpression();
+        } else if(symbol instanceof DerivedColumn) {
+            Expression expression = ((DerivedColumn)symbol).getExpression();
             tuple.add(new Evaluator(elementMap, getDataManager(), getContext()).evaluate(expression, values));
         } else {
             Assertion.failed(QueryExecPlugin.Util.getString(ErrorMessageKeys.PROCESSOR_0034, symbol.getClass().getName()));

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -36,6 +36,7 @@
 import com.metamatrix.common.buffer.TupleSourceID;
 import com.metamatrix.common.buffer.TupleSourceNotFoundException;
 import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
 
 public class SortNode extends RelationalNode {
 
@@ -68,7 +69,7 @@
         this.collector = null;
     }
 
-	public void setSortElements(List sortElements, List sortTypes) {
+	public void setSortElements(List<OrderByItem> sortElements) {
 		this.sortElements = sortElements;
 		this.sortTypes = sortTypes;
 	}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/DynamicCommandResolver.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/DynamicCommandResolver.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/DynamicCommandResolver.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -20,87 +20,87 @@
  * 02110-1301 USA.
  */
 
-package com.metamatrix.query.resolver.command;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import com.metamatrix.api.exception.MetaMatrixComponentException;
-import com.metamatrix.api.exception.query.QueryMetadataException;
-import com.metamatrix.api.exception.query.QueryResolverException;
-import com.metamatrix.common.types.DataTypeManager;
-import com.metamatrix.query.QueryPlugin;
-import com.metamatrix.query.analysis.AnalysisRecord;
-import com.metamatrix.query.metadata.TempMetadataAdapter;
-import com.metamatrix.query.metadata.TempMetadataID;
-import com.metamatrix.query.resolver.CommandResolver;
-import com.metamatrix.query.resolver.util.ResolverUtil;
-import com.metamatrix.query.resolver.util.ResolverVisitor;
-import com.metamatrix.query.resolver.util.ResolverVisitorUtil;
-import com.metamatrix.query.sql.ProcedureReservedWords;
-import com.metamatrix.query.sql.lang.Command;
-import com.metamatrix.query.sql.lang.DynamicCommand;
-import com.metamatrix.query.sql.lang.SetClause;
-import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
-
-public class DynamicCommandResolver implements CommandResolver {
-
-    /** 
-     * @see com.metamatrix.query.resolver.CommandResolver#resolveCommand(com.metamatrix.query.sql.lang.Command, boolean, TempMetadataAdapter, AnalysisRecord, boolean)
-     */
-    public void resolveCommand(Command command, boolean useMetadataCommands, TempMetadataAdapter metadata, AnalysisRecord analysis, boolean resolveNullLiterals) 
-        throws QueryMetadataException, QueryResolverException, MetaMatrixComponentException {
-
-        DynamicCommand dynamicCmd = (DynamicCommand)command;
-        
-        Iterator columns = dynamicCmd.getAsColumns().iterator();
-
-        Set groups = new HashSet();
-        
-        //if there is no into group, just create temp metadata ids
-        if (dynamicCmd.getIntoGroup() == null) {
-            while (columns.hasNext()) {
-                ElementSymbol column = (ElementSymbol)columns.next();
-                column.setMetadataID(new TempMetadataID(column.getShortCanonicalName(), column.getType()));
-            }
-        } else if (dynamicCmd.getIntoGroup().isTempGroupSymbol()) {
-            while (columns.hasNext()) {
-                ElementSymbol column = (ElementSymbol)columns.next();
-                column.setName(dynamicCmd.getIntoGroup().getCanonicalName() + SingleElementSymbol.SEPARATOR + column.getShortName());
-            }
-        }
-        
-        ResolverVisitor.resolveLanguageObject(dynamicCmd, groups, dynamicCmd.getExternalGroupContexts(), metadata);
-        
-        String sqlType = DataTypeManager.getDataTypeName(dynamicCmd.getSql().getType());
-        String targetType = DataTypeManager.DefaultDataTypes.STRING;
-        
-        if (!targetType.equals(sqlType) && !DataTypeManager.isImplicitConversion(sqlType, targetType)) {
-            throw new QueryResolverException(QueryPlugin.Util.getString("DynamicCommandResolver.SQL_String", sqlType)); //$NON-NLS-1$
-        }
-        
-        if (dynamicCmd.getUsing() != null && !dynamicCmd.getUsing().isEmpty()) {
-            for (SetClause clause : dynamicCmd.getUsing().getClauses()) {
-                ElementSymbol id = clause.getSymbol();
-                id.setName(ProcedureReservedWords.USING + SingleElementSymbol.SEPARATOR + id.getShortName());
-                id.setGroupSymbol(new GroupSymbol(ProcedureReservedWords.USING));
-                id.setType(clause.getValue().getType());
-                id.setMetadataID(new TempMetadataID(id.getCanonicalName(), id.getType()));
-            }
-        }
-        
-        GroupSymbol intoSymbol = dynamicCmd.getIntoGroup();
-        if (intoSymbol != null) {
-            if (!intoSymbol.isImplicitTempGroupSymbol()) {
-                ResolverVisitorUtil.resolveGroup(intoSymbol, metadata);
-            } else {
-                List symbols = dynamicCmd.getAsColumns();
-                ResolverUtil.resolveImplicitTempGroup(metadata, intoSymbol, symbols);
-            }
-        }
-    }
-}
+package com.metamatrix.query.resolver.command;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.query.QueryMetadataException;
+import com.metamatrix.api.exception.query.QueryResolverException;
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.query.QueryPlugin;
+import com.metamatrix.query.analysis.AnalysisRecord;
+import com.metamatrix.query.metadata.TempMetadataAdapter;
+import com.metamatrix.query.metadata.TempMetadataID;
+import com.metamatrix.query.resolver.CommandResolver;
+import com.metamatrix.query.resolver.util.ResolverUtil;
+import com.metamatrix.query.resolver.util.ResolverVisitor;
+import com.metamatrix.query.resolver.util.ResolverVisitorUtil;
+import com.metamatrix.query.sql.ProcedureReservedWords;
+import com.metamatrix.query.sql.lang.Command;
+import com.metamatrix.query.sql.lang.DynamicCommand;
+import com.metamatrix.query.sql.lang.SetClause;
+import com.metamatrix.query.sql.symbol.ElementSymbol;
+import com.metamatrix.query.sql.symbol.GroupSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
+
+public class DynamicCommandResolver implements CommandResolver {
+
+    /** 
+     * @see com.metamatrix.query.resolver.CommandResolver#resolveCommand(com.metamatrix.query.sql.lang.Command, boolean, TempMetadataAdapter, AnalysisRecord, boolean)
+     */
+    public void resolveCommand(Command command, boolean useMetadataCommands, TempMetadataAdapter metadata, AnalysisRecord analysis, boolean resolveNullLiterals) 
+        throws QueryMetadataException, QueryResolverException, MetaMatrixComponentException {
+
+        DynamicCommand dynamicCmd = (DynamicCommand)command;
+        
+        Iterator columns = dynamicCmd.getAsColumns().iterator();
+
+        Set groups = new HashSet();
+        
+        //if there is no into group, just create temp metadata ids
+        if (dynamicCmd.getIntoGroup() == null) {
+            while (columns.hasNext()) {
+                ElementSymbol column = (ElementSymbol)columns.next();
+                column.setMetadataID(new TempMetadataID(column.getShortCanonicalName(), column.getType()));
+            }
+        } else if (dynamicCmd.getIntoGroup().isTempGroupSymbol()) {
+            while (columns.hasNext()) {
+                ElementSymbol column = (ElementSymbol)columns.next();
+                column.setName(dynamicCmd.getIntoGroup().getCanonicalName() + Symbol.SEPARATOR + column.getShortName());
+            }
+        }
+        
+        ResolverVisitor.resolveLanguageObject(dynamicCmd, groups, dynamicCmd.getExternalGroupContexts(), metadata);
+        
+        String sqlType = DataTypeManager.getDataTypeName(dynamicCmd.getSql().getType());
+        String targetType = DataTypeManager.DefaultDataTypes.STRING;
+        
+        if (!targetType.equals(sqlType) && !DataTypeManager.isImplicitConversion(sqlType, targetType)) {
+            throw new QueryResolverException(QueryPlugin.Util.getString("DynamicCommandResolver.SQL_String", sqlType)); //$NON-NLS-1$
+        }
+        
+        if (dynamicCmd.getUsing() != null && !dynamicCmd.getUsing().isEmpty()) {
+            for (SetClause clause : dynamicCmd.getUsing().getClauses()) {
+                ElementSymbol id = clause.getSymbol();
+                id.setName(ProcedureReservedWords.USING + Symbol.SEPARATOR + id.getShortName());
+                id.setGroupSymbol(new GroupSymbol(ProcedureReservedWords.USING));
+                id.setType(clause.getValue().getType());
+                id.setMetadataID(new TempMetadataID(id.getCanonicalName(), id.getType()));
+            }
+        }
+        
+        GroupSymbol intoSymbol = dynamicCmd.getIntoGroup();
+        if (intoSymbol != null) {
+            if (!intoSymbol.isImplicitTempGroupSymbol()) {
+                ResolverVisitorUtil.resolveGroup(intoSymbol, metadata);
+            } else {
+                List symbols = dynamicCmd.getAsColumns();
+                ResolverUtil.resolveImplicitTempGroup(metadata, intoSymbol, symbols);
+            }
+        }
+    }
+}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -41,7 +41,7 @@
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.sql.lang.QueryCommand;
 import com.metamatrix.query.sql.lang.SetQuery;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.util.ErrorMessageKeys;
 
 public class SetQueryResolver implements CommandResolver {
@@ -59,10 +59,9 @@
         QueryResolver.setChildMetadata(firstCommand, setQuery);
         QueryResolver.resolveCommand(firstCommand, Collections.EMPTY_MAP, useMetadataCommands, metadata.getMetadata(), analysis, false);
 
-        List firstProject = firstCommand.getProjectedSymbols();
+        List<DerivedColumn> firstProject = firstCommand.getProjectedSymbols();
         List<Class<?>> firstProjectTypes = new ArrayList<Class<?>>();
-        for (Iterator j = firstProject.iterator(); j.hasNext();) {
-            SingleElementSymbol symbol = (SingleElementSymbol)j.next();
+        for (DerivedColumn symbol : firstProject) {
             firstProjectTypes.add(symbol.getType());
         }
 
@@ -111,10 +110,10 @@
                 continue;
             }
             SetQuery child = (SetQuery)subCommand;
-            List projectedSymbols = child.getProjectedSymbols();
+            List<DerivedColumn> projectedSymbols = child.getProjectedSymbols();
             if (child.getOrderBy() != null) {
                 for (int j = 0; j < projectedSymbols.size(); j++) {
-                    SingleElementSymbol ses = (SingleElementSymbol)projectedSymbols.get(j);
+                    DerivedColumn ses = projectedSymbols.get(j);
                     Class targetType = (Class)firstProjectTypes.get(j);
                     if (ses.getType() != targetType && ResolverUtil.orderByContainsVariable(child.getOrderBy(), ses, j)) {
                         String sourceTypeName = DataTypeManager.getDataTypeName(ses.getType());
@@ -129,10 +128,10 @@
         }
     }
     
-	static void checkSymbolTypes(List firstProjectTypes, List projSymbols) {
+	static void checkSymbolTypes(List firstProjectTypes, List<DerivedColumn> projSymbols) {
         for(int j=0; j<projSymbols.size(); j++){
             Class firstProjType = (Class)firstProjectTypes.get(j);
-    		SingleElementSymbol projSymbol = (SingleElementSymbol)projSymbols.get(j);
+    		DerivedColumn projSymbol = projSymbols.get(j);
             Class projType = projSymbol.getType();
             
             if(firstProjType.equals(projType)){

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SimpleQueryResolver.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SimpleQueryResolver.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/SimpleQueryResolver.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -75,15 +75,13 @@
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
 import com.metamatrix.query.sql.lang.UnaryFromClause;
 import com.metamatrix.query.sql.navigator.PostOrderNavigator;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.util.ErrorMessageKeys;
 import com.metamatrix.query.util.LogConstants;
 
@@ -556,7 +554,7 @@
                                 aliasName += "_IN"; //$NON-NLS-1$
                             }
                             
-                            SingleElementSymbol newSymbol = new AliasSymbol(aliasName, new ExpressionSymbol(paramSymbol.getShortName(), ref));
+                            DerivedColumn newSymbol = new DerivedColumn(aliasName, ref, true);
                             
                             select.addSymbol(newSymbol);
                             accessPatternElementNames.add(queryName + ElementSymbol.SEPARATOR + aliasName);
@@ -565,12 +563,11 @@
                     
                     QueryResolver.resolveCommand(procQuery, Collections.EMPTY_MAP, expandCommand, metadata.getMetadata(), analysis);
                     
-                    List projectedSymbols = procQuery.getProjectedSymbols();
+                    List<DerivedColumn> projectedSymbols = procQuery.getProjectedSymbols();
                     
-                    HashSet foundNames = new HashSet();
+                    HashSet<String> foundNames = new HashSet<String>();
                     
-                    for (Iterator i = projectedSymbols.iterator(); i.hasNext();) {
-                        SingleElementSymbol ses = (SingleElementSymbol)i.next();
+                    for (DerivedColumn ses : projectedSymbols) {
                         if (!foundNames.add(ses.getShortCanonicalName())) {
                             throw new QueryResolverException(QueryPlugin.Util.getString("SimpleQueryResolver.Proc_Relational_Name_conflict", fullName)); //$NON-NLS-1$                            
                         }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -69,7 +69,6 @@
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.util.SymbolMap;
 import com.metamatrix.query.util.ErrorMessageKeys;
 import com.metamatrix.query.util.LogConstants;
@@ -115,7 +114,7 @@
 	    	// then in the query transformation, this info is used in evaluating/validating
 	    	// has criteria/trnaslate criteria clauses
 			Command transformCmd = getQueryTransformCmd(virtualGroup, metadata);
-			Map symbolMap = SymbolMap.createSymbolMap(virtualGroup, (List<SingleElementSymbol>)transformCmd.getProjectedSymbols()).asMap();
+			Map symbolMap = SymbolMap.createSymbolMap(virtualGroup, transformCmd.getProjectedSymbols()).asMap();
 	        // set the symbolMap on the procedure
 			procCommand.setSymbolMap(symbolMap);
 		}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/XMLQueryResolver.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/XMLQueryResolver.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/command/XMLQueryResolver.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -47,11 +47,10 @@
 import com.metamatrix.query.sql.lang.OrderBy;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.Select;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.SelectSymbol;
 import com.metamatrix.query.sql.visitor.CommandCollectorVisitor;
@@ -145,7 +144,13 @@
 		for (int i = 0; i < elements.size(); i++) {
 			SelectSymbol ss = (SelectSymbol) elements.get(i);
 
-			if (ss instanceof ElementSymbol) {
+			if (ss instanceof DerivedColumn) {
+				DerivedColumn dc = (DerivedColumn)ss;
+				if (!(dc.getExpression() instanceof ElementSymbol)) {
+	                throw new QueryResolverException(QueryPlugin.Util.getString("XMLQueryResolver.no_expressions_in_select")); //$NON-NLS-1$
+	            } else if (dc.isAlias()) {
+	                throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0070, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0070));
+	            }
 				// Here we make an assumption that: all elements named with "xml" must use qualified name
 				// rather than a simple "xml" in order to distinguish it from "SELECT xml" and
 				// "SELECT model.document.xml" case, both of whom stand for selecting the whole document.
@@ -169,7 +174,7 @@
 					return;
 				}
                 // normal elements
-				resolveElement((ElementSymbol)ss, validElements, externalGroups, metadata);
+				resolveElement((ElementSymbol)dc.getExpression(), validElements, externalGroups, metadata);
 			} else if (ss instanceof AllInGroupSymbol) {
 				// Resolve the element with "*" case. such as "A.*"
 				// by stripping off the ".*" part,
@@ -197,12 +202,7 @@
                 AllSymbol all =  (AllSymbol)ss;
                 all.setElementSymbols(validElements);
 				return;
-			} else if (ss instanceof ExpressionSymbol) {
-                throw new QueryResolverException(QueryPlugin.Util.getString("XMLQueryResolver.no_expressions_in_select")); //$NON-NLS-1$
-            } else if (ss instanceof AliasSymbol) {
-                throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0070, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0070));
-            }
-            
+			} 
 		}
 	}
         

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -37,7 +37,6 @@
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.common.types.TransformationException;
 import com.metamatrix.common.types.DataTypeManager.DefaultDataTypes;
-import com.metamatrix.core.util.StringUtil;
 import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.function.FunctionDescriptor;
 import com.metamatrix.query.function.FunctionLibrary;
@@ -51,19 +50,18 @@
 import com.metamatrix.query.sql.LanguageObject;
 import com.metamatrix.query.sql.lang.Limit;
 import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
 import com.metamatrix.query.sql.symbol.AbstractCaseExpression;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
 import com.metamatrix.query.sql.symbol.SelectSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.visitor.ElementCollectorVisitor;
 import com.metamatrix.query.util.ErrorMessageKeys;
 
 /**
@@ -251,118 +249,118 @@
     * ones allowed to be in ORDER BY 
     * @param metadata QueryMetadataInterface
     */
-    public static void resolveOrderBy(OrderBy orderBy, List fromClauseGroups, List knownElements, QueryMetadataInterface metadata)
+    public static void resolveOrderBy(OrderBy orderBy, List<GroupSymbol> fromClauseGroups, List<DerivedColumn> knownElements, QueryMetadataInterface metadata)
         throws QueryResolverException, QueryMetadataException, MetaMatrixComponentException {
 
-        orderBy.setInPlanForm(false);
-        
         // Cached state, if needed
         String[] knownShortNames = null;
 
         // Collect all elements from order by
-        List elements = orderBy.getVariables();
-        Iterator elementIter = elements.iterator();
+        List<OrderByItem> elements = orderBy.getSortOrder();
 
         // Walk through elements of order by
-        while(elementIter.hasNext()){
-            ElementSymbol symbol = (ElementSymbol) elementIter.next();
-            SingleElementSymbol matchedSymbol = null;
-            String symbolName = symbol.getName();
-            String groupPart = metadata.getGroupName(symbolName);
-            String shortName = symbol.getShortName();
-            
-            //check for union order by (allow uuids to skip this check)
-            if (fromClauseGroups.isEmpty() && groupPart != null && !shortName.equals(symbolName)) {
-                throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0043, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0043, symbolName));
-            }
-
-            // construct the array of short names of the SELECT columns (once only)
-            if(knownShortNames == null) {
-                knownShortNames = new String[knownElements.size()];
-
-                for(int i=0; i<knownElements.size(); i++) {
-                    SingleElementSymbol knownSymbol = (SingleElementSymbol) knownElements.get(i);
-                    if (knownSymbol instanceof ExpressionSymbol) {
-                        continue;
-                    }
-                    
-                    String name = knownSymbol.getShortName();
-                    //special check for uuid element symbols
-                    if (knownSymbol instanceof ElementSymbol && knownSymbol.getShortName().equalsIgnoreCase(knownSymbol.getName())) {
-                        name = metadata.getShortElementName(metadata.getFullName((((ElementSymbol)knownSymbol).getMetadataID())));
-                    }  
-                    
-                    knownShortNames[i] = name;
-                }
-            }
-            // walk the SELECT col short names, looking for a match on the current ORDER BY 'short name'
-            for(int i=0; i<knownShortNames.length; i++) {
-            	if( shortName.equalsIgnoreCase( knownShortNames[i] )) {
-                    if (groupPart != null) {
-                        Object knownSymbol = knownElements.get(i);
-                        if(knownSymbol instanceof ElementSymbol) {
-                            ElementSymbol knownElement = (ElementSymbol) knownSymbol;
-                            GroupSymbol group = knownElement.getGroupSymbol();
-                            
-                            // skip this one if the two short names are not from the same group
-                            if (!nameMatchesGroup(groupPart.toUpperCase(), group.getCanonicalName())) {
-                                continue;
-                            }
-                        }
-                    }
-                    
-                    // if we already have a matched symbol, matching again here means it is duplicate/ambiguous
-                    if(matchedSymbol != null) {
-                        throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0042, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0042, symbolName));
-                    }
-                    matchedSymbol = (SingleElementSymbol)knownElements.get(i);
-                }
-            }
-                        
-            // this clause handles the order by clause like  
-            // select foo from bar order by "1"; where 1 is foo. 
-            if (matchedSymbol == null && StringUtil.isDigits(symbolName)) {
-                int elementOrder = Integer.valueOf(symbolName).intValue() - 1;
-                // adjust for the 1 based index.
-                if (elementOrder < knownElements.size() && elementOrder >= 0) {
-                    matchedSymbol = (SingleElementSymbol)knownElements.get(elementOrder);
-                    
-                    for(int i=0; i<knownShortNames.length; i++) {
-                        if (i == elementOrder) {
-                            continue;
-                        }
-                        if (matchedSymbol.getShortCanonicalName().equalsIgnoreCase(knownShortNames[i])) {
-                            throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0042, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0042, knownShortNames[i]));
-                        }
-                    }
-                }
-            }
-
-            if(matchedSymbol == null) {
-                // Didn't find it by full name or short name, so try resolving
-                // and retrying by full name - this will work for uuid case
-                try {
-                	ResolverVisitor.resolveLanguageObject(symbol, fromClauseGroups, metadata);
-                } catch(QueryResolverException e) {
-                	throw new QueryResolverException(e, ErrorMessageKeys.RESOLVER_0043, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0043, symbol.getName()) );
-                }
-
-                matchedSymbol = findMatchingElementByID(symbol, knownElements);
-            }
-                        
-            TempMetadataID tempMetadataID = new TempMetadataID(symbol.getName(), matchedSymbol.getType());
-            tempMetadataID.setPosition(knownElements.indexOf(matchedSymbol));
-            symbol.setMetadataID(tempMetadataID);
-            symbol.setType(matchedSymbol.getType());
+        for (OrderByItem orderByItem : elements) {
+        	Collection<ElementSymbol> symbols = ElementCollectorVisitor.getElements(orderByItem.getSortKey(), false);
+        	if (symbols.isEmpty()) {
+        		if (orderByItem.getSortKey() instanceof Constant) {
+        			Constant c = (Constant)orderByItem.getSortKey();
+        			if (DataTypeManager.DefaultDataClasses.INTEGER == c.getType()) {
+        				int value = (Integer)c.getValue();
+        				if (value < 0 || value > knownElements.size() -1) {
+        					throw new QueryResolverException("Invalid order by ordinal");
+        				}
+        				DerivedColumn matchedSymbol = knownElements.get(value);
+        				ElementSymbol symbol = new ElementSymbol(matchedSymbol.getName());
+        				resolveOrderByItem(value, symbol, matchedSymbol);
+        				continue;
+        			}
+        		}
+        		throw new QueryResolverException("Invalid order by expression");
+        	}
+        	for (ElementSymbol elementSymbol : symbols) {
+	            DerivedColumn matchedSymbol = null;
+	            String symbolName = elementSymbol.getName();
+	            String groupPart = metadata.getGroupName(symbolName);
+	            String shortName = elementSymbol.getShortName();
+	            
+	            //check for union order by (allow uuids to skip this check)
+	            if (fromClauseGroups.isEmpty() && groupPart != null && !shortName.equals(symbolName)) {
+	                throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0043, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0043, symbolName));
+	            }
+	
+	            // construct the array of short names of the SELECT columns (once only)
+	            if(knownShortNames == null) {
+	                knownShortNames = new String[knownElements.size()];
+	
+	                for(int i=0; i<knownElements.size(); i++) {
+	                    DerivedColumn knownSymbol = knownElements.get(i);
+	                    
+	                    String name = knownSymbol.getShortName();
+	                    
+	                    Expression expr = knownSymbol.getExpression();
+	                    //special check for uuid element symbols
+	                    if (expr instanceof ElementSymbol && knownSymbol.getShortName().equalsIgnoreCase(knownSymbol.getName())) {
+	                        name = metadata.getShortElementName(metadata.getFullName((((ElementSymbol)expr).getMetadataID())));
+	                    }  
+	                    
+	                    knownShortNames[i] = name;
+	                }
+	            }
+	            // walk the SELECT col short names, looking for a match on the current ORDER BY 'short name'
+	            for(int i=0; i<knownShortNames.length; i++) {
+	            	if( shortName.equalsIgnoreCase( knownShortNames[i] )) {
+	                    if (groupPart != null) {
+	                        Object knownSymbol = knownElements.get(i);
+	                        if(knownSymbol instanceof ElementSymbol) {
+	                            ElementSymbol knownElement = (ElementSymbol) knownSymbol;
+	                            GroupSymbol group = knownElement.getGroupSymbol();
+	                            
+	                            // skip this one if the two short names are not from the same group
+	                            if (!nameMatchesGroup(groupPart.toUpperCase(), group.getCanonicalName())) {
+	                                continue;
+	                            }
+	                        }
+	                    }
+	                    
+	                    // if we already have a matched symbol, matching again here means it is duplicate/ambiguous
+	                    if(matchedSymbol != null) {
+	                        throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0042, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0042, symbolName));
+	                    }
+	                    matchedSymbol = knownElements.get(i);
+	                    resolveOrderByItem(i, elementSymbol, matchedSymbol);
+	                }
+	            }
+	
+	            if(matchedSymbol == null) {
+	                // Didn't find it by full name or short name, so try resolving
+	                // and retrying by full name - this will work for uuid case
+	                try {
+	                	ResolverVisitor.resolveLanguageObject(elementSymbol, fromClauseGroups, metadata);
+	                } catch(QueryResolverException e) {
+	                	throw new QueryResolverException(e, ErrorMessageKeys.RESOLVER_0043, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0043, elementSymbol.getName()) );
+	                }
+	
+	                findMatchingElementByID(elementSymbol, knownElements);
+	            }	                        
+        	}
+        	ResolverVisitor.resolveLanguageObject(orderByItem.getSortKey(), metadata);
         }
     }
 
+	private static void resolveOrderByItem(int position,
+			ElementSymbol elementSymbol, DerivedColumn matchedSymbol) {
+		TempMetadataID tempMetadataID = new TempMetadataID(matchedSymbol.getName(), matchedSymbol.getType());
+		tempMetadataID.setPosition(position);
+		elementSymbol.setMetadataID(tempMetadataID);
+		elementSymbol.setType(matchedSymbol.getType());
+	}
+
     /**
      * Helper for resolveOrderBy to find a matching fully-qualified element in a list of
      * projected SELECT symbols.
      * @throws QueryResolverException 
      */
-    private static SingleElementSymbol findMatchingElementByID(ElementSymbol symbol, List knownElements) throws QueryResolverException {
+    private static void findMatchingElementByID(ElementSymbol symbol, List<DerivedColumn> knownElements) throws QueryResolverException {
         Object elementID = symbol.getMetadataID();
         
         if(elementID == null) {
@@ -372,20 +370,17 @@
         Object groupID = symbol.getGroupSymbol().getMetadataID();
 
         for(int i=0; i<knownElements.size(); i++) {
-            SingleElementSymbol selectSymbol = (SingleElementSymbol)knownElements.get(i);
-            SingleElementSymbol knownSymbol = null;
-            if(selectSymbol instanceof AliasSymbol) {
-            	knownSymbol = ((AliasSymbol)selectSymbol).getSymbol();
-            }
+            DerivedColumn selectSymbol = knownElements.get(i);
 
-            if(knownSymbol instanceof ElementSymbol) {
-                ElementSymbol knownElement = (ElementSymbol) knownSymbol;
+            if(selectSymbol.getExpression() instanceof ElementSymbol) {
+                ElementSymbol knownElement = (ElementSymbol) selectSymbol.getExpression();
                 Object knownElementID = knownElement.getMetadataID();
 
                 if(elementID.equals(knownElementID)) {
                     Object knownGroupID = knownElement.getGroupSymbol().getMetadataID();
                     if(groupID.equals(knownGroupID)) {
-                        return selectSymbol;
+                    	resolveOrderByItem(i, symbol, selectSymbol);
+                    	return;
                     }
                 }
             }
@@ -567,10 +562,10 @@
 
     public static void addTempGroup(TempMetadataAdapter metadata,
                                     GroupSymbol symbol,
-                                    List symbols, boolean tempTable) throws QueryResolverException {
+                                    List<DerivedColumn> symbols, boolean tempTable) throws QueryResolverException {
         HashSet names = new HashSet();
         for (Iterator i = symbols.iterator(); i.hasNext();) {
-            SingleElementSymbol ses = (SingleElementSymbol)i.next();
+            DerivedColumn ses = (DerivedColumn)i.next();
             if (!names.add(ses.getShortCanonicalName())) {
                 throw new QueryResolverException(QueryPlugin.Util.getString("ResolverUtil.duplicateName", symbol, ses.getShortName())); //$NON-NLS-1$
             }
@@ -597,48 +592,40 @@
      * @param select The select clause
      * @since 4.2
      */
-    public static void resolveNullLiterals(List symbols) {
-        for (int i = 0; i < symbols.size(); i++) {
-            SelectSymbol selectSymbol = (SelectSymbol) symbols.get(i);
-            
-            if (!(selectSymbol instanceof SingleElementSymbol)) {
+    public static void resolveNullLiterals(List<? extends SelectSymbol> symbols) {
+    	for (SelectSymbol selectSymbol : symbols) {
+            if (!(selectSymbol instanceof DerivedColumn)) {
                 continue;
             }
             
-            SingleElementSymbol symbol = (SingleElementSymbol)selectSymbol;
+            DerivedColumn symbol = (DerivedColumn)selectSymbol;
             
             if(!DataTypeManager.DefaultDataClasses.NULL.equals(symbol.getType()) && symbol.getType() != null) {
                 continue;
             }
-            if(symbol instanceof AliasSymbol) {
-                symbol = ((AliasSymbol)symbol).getSymbol();
-            }
+            
+            Expression expr = symbol.getExpression();
                         
             Class replacement = DataTypeManager.DefaultDataClasses.STRING;
-            
-            if(symbol instanceof ExpressionSymbol && !(symbol instanceof AggregateSymbol)) {
-                ExpressionSymbol exprSymbol = (ExpressionSymbol) symbol;
-                Expression expr = exprSymbol.getExpression();
-               	
-                if(expr instanceof Constant) {                	
-                    exprSymbol.setExpression(new Constant(null, replacement));
-                } else if (expr instanceof AbstractCaseExpression) {
-                    ((AbstractCaseExpression)expr).setType(replacement);
-                } else if (expr instanceof ScalarSubquery) {
-                    ((ScalarSubquery)expr).setType(replacement);                                        
-                } else {
-                	try {
-						ResolverUtil.setTypeIfReference(expr, replacement, symbol);
-					} catch (QueryResolverException e) {
-						//cannot happen
-					}
-                }
-            } else if(symbol instanceof ElementSymbol) {
-                ElementSymbol elementSymbol = (ElementSymbol)symbol;
+
+            if(expr instanceof ElementSymbol) {
+                ElementSymbol elementSymbol = (ElementSymbol)expr;
                 Class elementType = elementSymbol.getType();
                 if(elementType != null && elementType.equals(DataTypeManager.DefaultDataClasses.NULL)) {
                     elementSymbol.setType(replacement);
                 }
+            } else if(expr instanceof Constant) {                	
+                symbol.setExpression(new Constant(null, replacement));
+            } else if (expr instanceof AbstractCaseExpression) {
+                ((AbstractCaseExpression)expr).setType(replacement);
+            } else if (expr instanceof ScalarSubquery) {
+                ((ScalarSubquery)expr).setType(replacement);                                        
+            } else {
+            	try {
+					ResolverUtil.setTypeIfReference(expr, replacement, symbol);
+				} catch (QueryResolverException e) {
+					//cannot happen
+				}
             }
         }
     }
@@ -726,18 +713,9 @@
      * @param position 0-based index of the variable
      * @return True if the ORDER BY contains the element
      */
-    public static boolean orderByContainsVariable(OrderBy orderBy, SingleElementSymbol ses, int position) {
-        if (!orderBy.isInPlanForm()) {
-            for (final Iterator iterator = orderBy.getVariables().iterator(); iterator.hasNext();) {
-                final ElementSymbol element = (ElementSymbol)iterator.next();
-                if (position == ((TempMetadataID)element.getMetadataID()).getPosition()) {
-                    return true;
-                }
-            } 
-        } else {
-            return orderBy.getVariables().contains(ses);
-        }
-        return false;
+    public static boolean orderByContainsVariable(OrderBy orderBy, DerivedColumn ses, int position) {
+    	throw new UnsupportedOperationException();
+        //return false;
     }
     
 }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitorUtil.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitorUtil.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitorUtil.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -52,7 +52,7 @@
 import com.metamatrix.query.sql.lang.MatchCriteria;
 import com.metamatrix.query.sql.lang.SetCriteria;
 import com.metamatrix.query.sql.lang.SubqueryContainer;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
@@ -146,8 +146,8 @@
     	Expression leftExpression = ccrit.getLeftExpression();
     	Expression rightExpression = ccrit.getRightExpression();
     
-    	boolean leftIsAggregate = (leftExpression instanceof AggregateSymbol);
-    	boolean rightIsAggregate = (rightExpression instanceof AggregateSymbol);
+    	boolean leftIsAggregate = (leftExpression instanceof Aggregate);
+    	boolean rightIsAggregate = (rightExpression instanceof Aggregate);
     
     	// Check typing between expressions
         ResolverUtil.setTypeIfReference(leftExpression, rightExpression.getType(), ccrit);
@@ -205,7 +205,7 @@
                         // both are aggs of differing types - can't reconcile
                         throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0064, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0064));
                     }
-                    AggregateSymbol aggRight = (AggregateSymbol) rightExpression;
+                    Aggregate aggRight = (Aggregate) rightExpression;
                     String aggFunc = aggRight.getAggregateFunction();
                     // Convert expression inside MIN/MAX function rather than converting aggregate
                     if((aggFunc.equals(ReservedWords.MIN) || aggFunc.equals(ReservedWords.MAX)) &&
@@ -215,7 +215,7 @@
                         throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0028, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0028));
                     }
                 } else if(leftIsAggregate) {
-                    AggregateSymbol aggLeft = (AggregateSymbol) leftExpression;
+                    Aggregate aggLeft = (Aggregate) leftExpression;
                     String aggFunc = aggLeft.getAggregateFunction();
                     // Convert expression inside MIN/MAX function rather than converting aggregate
                     if((aggFunc.equals(ReservedWords.MIN) || aggFunc.equals(ReservedWords.MAX)) &&
@@ -264,12 +264,12 @@
             if (! type.equals(DataTypeManager.DefaultDataTypes.STRING) &&
                 ! type.equals(DataTypeManager.DefaultDataTypes.CLOB)) {
                     
-                if(!(expr instanceof AggregateSymbol) &&
+                if(!(expr instanceof Aggregate) &&
                     ResolverUtil.canImplicitlyConvert(type, DataTypeManager.DefaultDataTypes.STRING)) {
     
                     result = ResolverUtil.convertExpression(expr, type, DataTypeManager.DefaultDataTypes.STRING);
                     
-                } else if (!(expr instanceof AggregateSymbol) &&
+                } else if (!(expr instanceof Aggregate) &&
                     ResolverUtil.canImplicitlyConvert(type, DataTypeManager.DefaultDataTypes.CLOB)){
                         
                     result = ResolverUtil.convertExpression(expr, type, DataTypeManager.DefaultDataTypes.CLOB);
@@ -303,7 +303,7 @@
             Expression value = (Expression) valIter.next();
             ResolverUtil.setTypeIfReference(value, exprType, scrit);
             if(! value.getType().equals(exprType)) {
-                if(value instanceof AggregateSymbol) {
+                if(value instanceof Aggregate) {
                     throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0031, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0031, scrit));
                 }
                 // try to apply cast

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -124,18 +124,16 @@
 import com.metamatrix.query.sql.proc.Statement;
 import com.metamatrix.query.sql.proc.TranslateCriteria;
 import com.metamatrix.query.sql.proc.WhileStatement;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
 import com.metamatrix.query.sql.symbol.SearchedCaseExpression;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.util.SymbolMap;
 import com.metamatrix.query.sql.visitor.AggregateSymbolCollectorVisitor;
 import com.metamatrix.query.sql.visitor.CorrelatedVariableSubstitutionVisitor;
@@ -699,7 +697,7 @@
             // we check for group by expressions here to create an ANSI SQL plan
             boolean hasExpression = false;
             for (final Iterator iterator = query.getGroupBy().getSymbols().iterator(); !hasExpression && iterator.hasNext();) {
-                hasExpression = iterator.next() instanceof ExpressionSymbol;
+                hasExpression = iterator.next() instanceof DerivedColumn;
             } 
             if (hasExpression) {
                 Select select = query.getSelect();
@@ -717,12 +715,12 @@
                 for (final Iterator iterator = groupBy.getSymbols().iterator(); iterator.hasNext();) {
                     newSelectColumns.add(SymbolMap.getExpression((SingleElementSymbol)iterator.next()));
                 }
-                Set<AggregateSymbol> aggs = new HashSet<AggregateSymbol>();
+                Set<Aggregate> aggs = new HashSet<Aggregate>();
                 aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(select, true));
                 if (having != null) {
                     aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(having, true));
                 }
-                for (AggregateSymbol aggregateSymbol : aggs) {
+                for (Aggregate aggregateSymbol : aggs) {
                     if (aggregateSymbol.getExpression() != null) {
                         Expression expr = aggregateSymbol.getExpression();
                         newSelectColumns.add(SymbolMap.getExpression(expr));
@@ -734,7 +732,7 @@
                     if (expr instanceof SingleElementSymbol) {
                         innerSelect.addSymbol((SingleElementSymbol)expr);
                     } else {
-                        innerSelect.addSymbol(new ExpressionSymbol("EXPR" + index++ , expr)); //$NON-NLS-1$
+                        innerSelect.addSymbol(new DerivedColumn("EXPR" + index++ , expr)); //$NON-NLS-1$
                     }
                 }
                 query.setSelect(innerSelect);
@@ -1982,21 +1980,20 @@
         } else if (expression instanceof ScalarSubquery) {
             rewriteSubqueryContainer((ScalarSubquery)expression, procCommand, context, metadata);
             return expression;
-        } else if (expression instanceof ExpressionSymbol && !(expression instanceof AggregateSymbol)) {
-            return rewriteExpression(((ExpressionSymbol)expression).getExpression(), procCommand, context, metadata);
-        } else if(expression instanceof AggregateSymbol){
-        	return rewriteExpression((AggregateSymbol)expression);
+        } else if (expression instanceof DerivedColumn && !(expression instanceof Aggregate)) {
+            return rewriteExpression(((DerivedColumn)expression).getExpression(), procCommand, context, metadata);
+        } else if(expression instanceof Aggregate){
+        	return rewriteExpression((Aggregate)expression);
         }
         return expression;
 	}
 
-    private static Expression rewriteExpression(AggregateSymbol expression) {
+    private static Expression rewriteExpression(Aggregate expression) {
     	if (!expression.getAggregateFunction().equals(ReservedWords.COUNT)
 				&& !expression.getAggregateFunction().equals(ReservedWords.SUM)
 				&& EvaluateExpressionVisitor.willBecomeConstant(expression.getExpression())) {
 			try {
-				return new ExpressionSymbol(expression.getName(), ResolverUtil
-						.convertExpression(expression.getExpression(),DataTypeManager.getDataTypeName(expression.getType())));
+				return ResolverUtil.convertExpression(expression.getExpression(),DataTypeManager.getDataTypeName(expression.getType()));
 			} catch (QueryResolverException e) {
 				//should not happen, so throw as a runtime
 				throw new MetaMatrixRuntimeException(e);
@@ -2454,7 +2451,7 @@
                 name = baseName + '_' + (exprID++);
             }
             
-            if (expressionSymbolsOnly && !(symbol instanceof ExpressionSymbol)) {
+            if (expressionSymbolsOnly && !(symbol instanceof DerivedColumn)) {
                 continue;
             }
             
@@ -2465,7 +2462,7 @@
                 hasAlias = true;
             }
             
-            if (((symbol instanceof ExpressionSymbol) && !hasAlias) || !name.equalsIgnoreCase(baseName)) {
+            if (((symbol instanceof DerivedColumn) && !hasAlias) || !name.equalsIgnoreCase(baseName)) {
                 symbols.set(i, new AliasSymbol(name, symbol));
             }
         }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/LanguageVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/LanguageVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/LanguageVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -22,9 +22,70 @@
 
 package com.metamatrix.query.sql;
 
-import com.metamatrix.query.sql.lang.*;
-import com.metamatrix.query.sql.symbol.*;
-import com.metamatrix.query.sql.proc.*;
+import com.metamatrix.query.sql.lang.BatchedUpdateCommand;
+import com.metamatrix.query.sql.lang.BetweenCriteria;
+import com.metamatrix.query.sql.lang.BulkInsert;
+import com.metamatrix.query.sql.lang.CompareCriteria;
+import com.metamatrix.query.sql.lang.CompoundCriteria;
+import com.metamatrix.query.sql.lang.Create;
+import com.metamatrix.query.sql.lang.Delete;
+import com.metamatrix.query.sql.lang.DependentSetCriteria;
+import com.metamatrix.query.sql.lang.Drop;
+import com.metamatrix.query.sql.lang.DynamicCommand;
+import com.metamatrix.query.sql.lang.ExistsCriteria;
+import com.metamatrix.query.sql.lang.From;
+import com.metamatrix.query.sql.lang.GroupBy;
+import com.metamatrix.query.sql.lang.Insert;
+import com.metamatrix.query.sql.lang.Into;
+import com.metamatrix.query.sql.lang.IsNullCriteria;
+import com.metamatrix.query.sql.lang.JoinPredicate;
+import com.metamatrix.query.sql.lang.JoinType;
+import com.metamatrix.query.sql.lang.Limit;
+import com.metamatrix.query.sql.lang.MatchCriteria;
+import com.metamatrix.query.sql.lang.NotCriteria;
+import com.metamatrix.query.sql.lang.Option;
+import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
+import com.metamatrix.query.sql.lang.ProcedureContainer;
+import com.metamatrix.query.sql.lang.Query;
+import com.metamatrix.query.sql.lang.Select;
+import com.metamatrix.query.sql.lang.SetClause;
+import com.metamatrix.query.sql.lang.SetClauseList;
+import com.metamatrix.query.sql.lang.SetCriteria;
+import com.metamatrix.query.sql.lang.SetQuery;
+import com.metamatrix.query.sql.lang.StoredProcedure;
+import com.metamatrix.query.sql.lang.SubqueryCompareCriteria;
+import com.metamatrix.query.sql.lang.SubqueryFromClause;
+import com.metamatrix.query.sql.lang.SubquerySetCriteria;
+import com.metamatrix.query.sql.lang.UnaryFromClause;
+import com.metamatrix.query.sql.lang.Update;
+import com.metamatrix.query.sql.lang.XQuery;
+import com.metamatrix.query.sql.proc.AssignmentStatement;
+import com.metamatrix.query.sql.proc.Block;
+import com.metamatrix.query.sql.proc.BreakStatement;
+import com.metamatrix.query.sql.proc.CommandStatement;
+import com.metamatrix.query.sql.proc.ContinueStatement;
+import com.metamatrix.query.sql.proc.CreateUpdateProcedureCommand;
+import com.metamatrix.query.sql.proc.CriteriaSelector;
+import com.metamatrix.query.sql.proc.DeclareStatement;
+import com.metamatrix.query.sql.proc.HasCriteria;
+import com.metamatrix.query.sql.proc.IfStatement;
+import com.metamatrix.query.sql.proc.LoopStatement;
+import com.metamatrix.query.sql.proc.RaiseErrorStatement;
+import com.metamatrix.query.sql.proc.TranslateCriteria;
+import com.metamatrix.query.sql.proc.WhileStatement;
+import com.metamatrix.query.sql.symbol.Aggregate;
+import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
+import com.metamatrix.query.sql.symbol.AllSymbol;
+import com.metamatrix.query.sql.symbol.CaseExpression;
+import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
+import com.metamatrix.query.sql.symbol.ElementSymbol;
+import com.metamatrix.query.sql.symbol.Function;
+import com.metamatrix.query.sql.symbol.GroupSymbol;
+import com.metamatrix.query.sql.symbol.Reference;
+import com.metamatrix.query.sql.symbol.ScalarSubquery;
+import com.metamatrix.query.sql.symbol.SearchedCaseExpression;
 
 /**
  * <p>The LanguageVisitor can be used to visit a LanguageObject as if it were a tree
@@ -91,13 +152,12 @@
     public void visit(Drop obj) {}
 
     // Visitor methods for symbol objects
-    public void visit(AggregateSymbol obj) {}
-    public void visit(AliasSymbol obj) {}
+    public void visit(Aggregate obj) {}
     public void visit(AllInGroupSymbol obj) {}
     public void visit(AllSymbol obj) {}
     public void visit(Constant obj) {}
     public void visit(ElementSymbol obj) {}
-    public void visit(ExpressionSymbol obj) {}
+    public void visit(DerivedColumn obj) {}
     public void visit(Function obj) {}
     public void visit(GroupSymbol obj) {}
     public void visit(Reference obj) {}
@@ -126,4 +186,5 @@
     public void visit(ProcedureContainer obj) {}
     public void visit(SetClauseList obj) {}
     public void visit(SetClause obj) {}
+    public void visit(OrderByItem obj) {}
 }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Command.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Command.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Command.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -22,15 +22,22 @@
 
 package com.metamatrix.query.sql.lang;
 
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 import com.metamatrix.api.exception.MetaMatrixComponentException;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.sql.LanguageObject;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.visitor.CommandCollectorVisitor;
 import com.metamatrix.query.sql.visitor.SQLStringVisitor;
 
@@ -98,7 +105,7 @@
     
     public static final int TYPE_DROP = 12;
 
-    private static List updateCommandSymbol = null;
+    private static List<DerivedColumn> updateCommandSymbol = null;
     
     private static List updatesCommandSymbol = null;
     
@@ -280,7 +287,7 @@
 	 * single column.
 	 * @return Ordered list of SingleElementSymbol
 	 */
-	public abstract List<SingleElementSymbol> getProjectedSymbols();
+	public abstract List<DerivedColumn> getProjectedSymbols();
 
 	/**
 	 * Whether the results are cachable.
@@ -288,11 +295,11 @@
 	 */
 	public abstract boolean areResultsCachable();
     
-    public static List getUpdateCommandSymbol() {
+    public static List<DerivedColumn> getUpdateCommandSymbol() {
         if (updateCommandSymbol == null ) {
             ElementSymbol symbol = new ElementSymbol("Count"); //$NON-NLS-1$
             symbol.setType(DataTypeManager.DefaultDataClasses.INTEGER);
-            updateCommandSymbol = Arrays.asList(new ElementSymbol[] {symbol});
+            updateCommandSymbol = Arrays.asList(new DerivedColumn(symbol));
         }
         return updateCommandSymbol;
     }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/GroupBy.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/GroupBy.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/GroupBy.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -46,7 +46,7 @@
 public class GroupBy implements LanguageObject {
 
     /** The set of expressions for the data elements to be group. */
-    private List symbols;     // List<Expression>
+    private List<Expression> symbols;     // List<Expression>
 
     // =========================================================================
     //                         C O N S T R U C T O R S
@@ -56,15 +56,15 @@
      * Constructs a default instance of this class.
      */
     public GroupBy() {
-        symbols = new ArrayList();
+        symbols = new ArrayList<Expression>();
     }
 
     /**
      * Constructs an instance of this class from an ordered set of symbols.
      * @param symbols The ordered list of {@link com.metamatrix.query.sql.symbol.ElementSymbol}s
      */
-    public GroupBy( List symbols ) {
-        this.symbols = new ArrayList( symbols );
+    public GroupBy( List<? extends Expression> symbols ) {
+        this.symbols = new ArrayList<Expression>( symbols );
     }
 
     // =========================================================================
@@ -83,7 +83,7 @@
      * Returns an ordered list of the symbols in the GROUP BY
      * @return List of {@link com.metamatrix.query.sql.symbol.ElementSymbol}s
      */
-    public List getSymbols() {
+    public List<Expression> getSymbols() {
         return symbols;
     }
 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Insert.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Insert.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Insert.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -36,7 +36,7 @@
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 
 /**
  * Represents a SQL Insert statement of the form:
@@ -226,7 +226,7 @@
         
         for (int j = 0; j < iSize; j++) {
             ElementSymbol symbol = (ElementSymbol)((ElementSymbol)variables.get( j )).clone();
-            symbol.setName(ProcedureReservedWords.INPUT + SingleElementSymbol.SEPARATOR + symbol.getShortCanonicalName());
+            symbol.setName(ProcedureReservedWords.INPUT + Symbol.SEPARATOR + symbol.getShortCanonicalName());
             map.put(symbol, values.get( j ) );
         } // for 
         return map;

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderBy.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderBy.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderBy.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -23,18 +23,15 @@
 package com.metamatrix.query.sql.lang;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
 
 import com.metamatrix.core.util.EquivalenceUtil;
 import com.metamatrix.core.util.HashCodeUtil;
-import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.sql.LanguageObject;
 import com.metamatrix.query.sql.LanguageVisitor;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.lang.OrderByItem.OrderSpecification;
+import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.visitor.SQLStringVisitor;
-import com.metamatrix.query.util.ErrorMessageKeys;
 
 /**
  * Represents the ORDER BY clause of a query.  The ORDER BY clause states
@@ -45,46 +42,26 @@
  */
 public class OrderBy implements LanguageObject {
 
-	/** Constant for the ascending value */
-    public static final boolean ASC = Boolean.TRUE.booleanValue();
+	private List<OrderByItem> sortOrder;
 
-	/** Constant for the descending value */
-    public static final boolean DESC = Boolean.FALSE.booleanValue();
-
-	private List sortOrder;
-    private List orderTypes;
-    private boolean inPlanForm = true;
-
     /**
      * Constructs a default instance of this class.
      */
     public OrderBy() {
-    	sortOrder = new ArrayList();
-        orderTypes = new ArrayList();
+    	sortOrder = new ArrayList<OrderByItem>();
     }
 
     /**
      * Constructs an instance of this class from an ordered set of elements.
      * @param parameters The ordered list of SingleElementSymbol
      */
-    public OrderBy( List parameters ) {
-        sortOrder = new ArrayList( parameters );
-        orderTypes = new ArrayList(parameters.size());
+    public OrderBy( List<Expression> parameters ) {
+        sortOrder = new ArrayList<OrderByItem>( );
         for( int i=0; i< parameters.size(); i++) {
-        	orderTypes.add(Boolean.TRUE);
+        	sortOrder.add(new OrderByItem(parameters.get(i), OrderSpecification.ASC));
         }
     }
 
-    /**
-     * Constructs an instance of this class from an ordered set of elements.
-     * @param parameters The ordered list of SingleElementSymbol
-     * @param types The list of directions by which the results are ordered (Boolean, true=ascending)
-     */
-    public OrderBy( List parameters, List types ) {
-        sortOrder = new ArrayList( parameters );
-        orderTypes = new ArrayList( types );
-    }
-
     // =========================================================================
     //                             M E T H O D S
     // =========================================================================
@@ -96,49 +73,26 @@
         return sortOrder.size();
     }
 
-    /**
-     * Returns an ordered list of the symbols in ORDER BY
-     * @param List of SingleElementSymbol in ORDER BY
-     */
-    public List getVariables() {
-        return sortOrder;
-    }
+    public List<OrderByItem> getSortOrder() {
+		return sortOrder;
+	}
 
     /**
-     * Returns an ordered list of sort direction for each order.
-     * @param List of Boolean, Boolean.TRUE represents ascending
+     * Adds a new variable to the list of order by elements.
+     * @param element Element to add
      */
-    public List getTypes() {
-        return orderTypes;
+    public void addVariable( Expression element ) {
+    	addVariable(element, null);
     }
-
+    
     /**
-     * Returns the ORDER BY element at the specified index.
-     * @param index Index to get
-     * @return The element at the index
-     */
-    public SingleElementSymbol getVariable( int index ) {
-        return (SingleElementSymbol)sortOrder.get(index);
-    }
-
-    /**
-     * Returns the sort order at the specified index
-     * @param index Index to get
-     * @return The sort order at the index
-     */
-    public Boolean getOrderType( int index ) {
-        return (Boolean)orderTypes.get(index);
-    }
-
-    /**
-     * Adds a new variable to the list of order by elements.
+     * Adds a new variable to the list of order by elements with the
+     * specified sort order
      * @param element Element to add
+     * @param type True for ascending, false for descending
      */
-    public void addVariable( SingleElementSymbol element ) {
-    	if(element != null) {
-	        sortOrder.add(element);
-            orderTypes.add(Boolean.valueOf(ASC));
-        }
+    public void addVariable( Expression element, boolean type ) {
+    	addVariable(element, type?OrderSpecification.ASC:OrderSpecification.DESC);
     }
 
     /**
@@ -147,30 +101,16 @@
      * @param element Element to add
      * @param type True for ascending, false for descending
      */
-    public void addVariable( SingleElementSymbol element, boolean type ) {
+    public void addVariable( Expression element, OrderSpecification type ) {
     	if(element != null) {
-	        sortOrder.add(element);
-            orderTypes.add(Boolean.valueOf(type));
+	        sortOrder.add(new OrderByItem(element, type));
         }
     }
     
-    /**
-     * Sets a new collection of variables to be used.  The replacement
-     * set must be of the same size as the previous set.
-     * @param elements Collection of SingleElementSymbol
-     * @throws IllegalArgumentException if element is null or size of elements != size of existing elements
-     */
-    public void replaceVariables( Collection elements ) {
-		if(elements == null) {
-            throw new IllegalArgumentException(QueryPlugin.Util.getString(ErrorMessageKeys.SQL_0004));
-		}
-		if(elements.size() != sortOrder.size()) {
-            throw new IllegalArgumentException(QueryPlugin.Util.getString(ErrorMessageKeys.SQL_0005));
-		}
-
-        sortOrder = new ArrayList(elements);
+    public void addItem(OrderByItem item) {
+    	this.sortOrder.add(item);
     }
-
+    
     public void acceptVisitor(LanguageVisitor visitor) {
         visitor.visit(this);
     }
@@ -183,15 +123,10 @@
      * Return deep copy of this ORDER BY clause.
      */
     public Object clone() {
-	    List thisSymbols = getVariables();
-	    List copySymbols = new ArrayList(thisSymbols.size());
-	    Iterator iter = thisSymbols.iterator();
-	    while(iter.hasNext()) {
-	    	SingleElementSymbol ses = (SingleElementSymbol) iter.next();
-	    	copySymbols.add(ses.clone());
-	    }
-		OrderBy result = new OrderBy(copySymbols, getTypes());
-		result.setInPlanForm(this.inPlanForm);
+		OrderBy result = new OrderBy();
+		for (OrderByItem item : sortOrder) {
+			result.addItem((OrderByItem)item.clone());
+		}
         return result;
 	}
 
@@ -211,8 +146,7 @@
 		}
 
 		OrderBy other = (OrderBy) obj;
-        return EquivalenceUtil.areEqual(getVariables(), other.getVariables()) &&
-               EquivalenceUtil.areEqual(getTypes(), other.getTypes());
+        return EquivalenceUtil.areEqual(getSortOrder(), other.getSortOrder());
 	}
 
 	/**
@@ -223,10 +157,7 @@
 	 * @return Hash code
 	 */
 	public int hashCode() {
-        int hc = 0;
-		hc = HashCodeUtil.hashCode(0, getVariables());
-        hc = HashCodeUtil.hashCode(hc, getTypes());
-        return hc;
+        return HashCodeUtil.hashCode(0, getSortOrder());
 	}
 
     /**
@@ -237,12 +168,4 @@
     	return SQLStringVisitor.getSQLString(this);
     }
 
-    public boolean isInPlanForm() {
-        return this.inPlanForm;
-    }
-
-    public void setInPlanForm(boolean inPlanForm) {
-        this.inPlanForm = inPlanForm;
-    }
-
 }

Added: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderByItem.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderByItem.java	                        (rev 0)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderByItem.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -0,0 +1,74 @@
+package com.metamatrix.query.sql.lang;
+
+import com.metamatrix.query.sql.LanguageObject;
+import com.metamatrix.query.sql.LanguageVisitor;
+import com.metamatrix.query.sql.symbol.Expression;
+import com.metamatrix.query.sql.visitor.SQLStringVisitor;
+
+public class OrderByItem implements LanguageObject {
+	
+	public enum OrderSpecification {
+		ASC,
+		DESC
+	}
+
+	private Expression sortKey;
+	private OrderSpecification orderingSpecification;
+	
+	public OrderByItem(Expression sortKey, OrderSpecification orderingSpecification) {
+		this.orderingSpecification = orderingSpecification;
+		this.sortKey = sortKey;
+	}
+
+	public Expression getSortKey() {
+		return sortKey;
+	}
+	
+	public void setSortKey(Expression sortKey) {
+		this.sortKey = sortKey;
+	}
+	
+	public OrderSpecification getOrderingSpecification() {
+		if (orderingSpecification == null) {
+			return OrderSpecification.ASC;
+		}
+		return orderingSpecification;
+	}
+	
+	public void setOrderingSpecification(
+			OrderSpecification orderingSpecification) {
+		this.orderingSpecification = orderingSpecification;
+	}
+	
+	@Override
+	public void acceptVisitor(LanguageVisitor visitor) {
+		visitor.visit(this);
+	}
+	
+	@Override
+	public Object clone() {
+		return new OrderByItem((Expression)sortKey.clone(), orderingSpecification);
+	}
+	
+	@Override
+	public int hashCode() {
+		return sortKey.hashCode();
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+		if (!(obj instanceof OrderByItem)) {
+			return false;
+		}
+		OrderByItem other = (OrderByItem)obj;
+		return sortKey.equals(other.sortKey) && (this.getOrderingSpecification() == other.getOrderingSpecification());
+	}
+	
+	@Override
+	public String toString() {
+		return SQLStringVisitor.getSQLString(this);
+	}
+}


Property changes on: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/OrderByItem.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Query.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Query.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Query.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -24,7 +24,6 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 
 import com.metamatrix.api.exception.MetaMatrixComponentException;
@@ -33,9 +32,8 @@
 import com.metamatrix.core.util.HashCodeUtil;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.sql.LanguageVisitor;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.SelectSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 /**
  * A representation of a data query.  A query consists of various parts,
  * referred to as clauses.  The following list the types of clauses
@@ -75,9 +73,6 @@
     /** The into clause. */
     private Into into;
     
-    /** xml projected symbols */
-    private List selectList;
-	
     // =========================================================================
     //                         C O N S T R U C T O R S
     // =========================================================================
@@ -292,7 +287,7 @@
 	 * single column.
 	 * @return Ordered list of SingleElementSymbol
 	 */
-	public List getProjectedSymbols() {
+	public List<DerivedColumn> getProjectedSymbols() {
 		if (!getIsXML()) {
 			if(getSelect() != null) { 
                 if(getInto() != null){
@@ -301,14 +296,12 @@
                 }
 				return getSelect().getProjectedSymbols();
 			}
-			return Collections.EMPTY_LIST;
+			return Collections.emptyList();
 		}
-		if(selectList == null){
-			selectList = new ArrayList(1);
-			ElementSymbol xmlElement = new ElementSymbol("xml"); //$NON-NLS-1$
-	        xmlElement.setType(DataTypeManager.DefaultDataClasses.XML);
-			selectList.add(xmlElement);
-		}
+		List<DerivedColumn> selectList = new ArrayList<DerivedColumn>(1);
+		ElementSymbol xmlElement = new ElementSymbol("xml"); //$NON-NLS-1$
+        xmlElement.setType(DataTypeManager.DefaultDataClasses.XML);
+		selectList.add(new DerivedColumn(xmlElement));
 		return selectList;
 	}
 	
@@ -358,14 +351,6 @@
         // Defect 13751: should clone isXML state.
         copy.setIsXML(getIsXML());
         
-        if(selectList != null){
-        	copy.selectList = new ArrayList();
-            Iterator iter = selectList.iterator();
-            while(iter.hasNext()) {
-            	copy.selectList.add(((SelectSymbol)iter.next()).clone());
-            }
-        }
-        
         copyMetadataState(copy);
         
 		return copy;
@@ -425,10 +410,8 @@
 		if(this.getInto() != null){
 			return false;
 		}
-		List projectedSymbols = getProjectedSymbols();
-		for(int i=0; i<projectedSymbols.size(); i++){
-			SingleElementSymbol projectedSymbol = (SingleElementSymbol)projectedSymbols.get(i);
-			if(DataTypeManager.isLOB(projectedSymbol.getType())) {
+		for (DerivedColumn column : getProjectedSymbols()) {
+			if(DataTypeManager.isLOB(column.getType())) {
 				return false;
 			}
 		}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Select.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Select.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Select.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -22,12 +22,20 @@
 
 package com.metamatrix.query.sql.lang;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 
-import com.metamatrix.core.util.HashCodeUtil;
-import com.metamatrix.query.sql.symbol.*;
-import com.metamatrix.query.sql.*;
 import com.metamatrix.core.util.EquivalenceUtil;
+import com.metamatrix.core.util.HashCodeUtil;
+import com.metamatrix.query.sql.LanguageObject;
+import com.metamatrix.query.sql.LanguageVisitor;
+import com.metamatrix.query.sql.symbol.AllSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
+import com.metamatrix.query.sql.symbol.ElementSymbol;
+import com.metamatrix.query.sql.symbol.MultipleElementSymbol;
+import com.metamatrix.query.sql.symbol.SelectSymbol;
 import com.metamatrix.query.sql.visitor.SQLStringVisitor;
 
 /**
@@ -37,7 +45,7 @@
 public class Select implements LanguageObject {
 
     /** The set of symbols for the data elements to be selected. */
-    private List symbols;     // List<SelectSymbols>
+    private List<SelectSymbol> symbols; 
 
     /** Flag for whether duplicate removal should be performed on the results */
     private boolean distinct;
@@ -50,15 +58,15 @@
      * Constructs a default instance of this class.
      */
     public Select() {
-        symbols = new ArrayList();
+        symbols = new ArrayList<SelectSymbol>();
     }
 
     /**
      * Constructs an instance of this class from an ordered set of symbols.
      * @param symbols The ordered list of symbols
      */
-    public Select( List symbols ) {
-        this.symbols = new ArrayList( symbols );
+    public Select( List<? extends SelectSymbol> symbols ) {
+        this.symbols = new ArrayList<SelectSymbol>( symbols );
     }
 
     // =========================================================================
@@ -84,7 +92,7 @@
      * Returns an ordered list of the symbols in the select.
      * @param Get list of SelectSymbol in SELECT
      */
-    public List getSymbols() {
+    public List<SelectSymbol> getSymbols() {
         return symbols;
     }
     
@@ -92,7 +100,7 @@
      * Sets an ordered list of the symbols in the select.
      * @param symbols list of SelectSymbol in SELECT
      */
-    public void setSymbols(List symbols) {
+    public void setSymbols(List<SelectSymbol> symbols) {
         this.symbols = symbols;
     }    
 
@@ -102,7 +110,7 @@
      * @return The variable identifier at the index
      */
     public SelectSymbol getSymbol( int index ) {
-        return (SelectSymbol) symbols.get(index);
+        return symbols.get(index);
     }
 
     /**
@@ -114,12 +122,18 @@
 	        symbols.add(symbol);
         }
     }
+    
+    public void addSymbol(ElementSymbol symbol) {
+    	if (symbol != null) {
+    		symbols.add(new DerivedColumn(symbol));
+    	}
+    }
 
     /**
      * Adds a new collection of symbols to the list of symbols.
      * @param symbols Collection of SelectSymbols
      */
-    public void addSymbols( Collection symbols) {
+    public void addSymbols( Collection<SelectSymbol> symbols) {
     	if(symbols != null) {
 	        this.symbols.addAll(symbols);
         }
@@ -141,38 +155,6 @@
         return symbols.contains(symbol);
     }
 
-    /**
-     * Check is the element symbol is being selected by this
-     * select clause.  This includes checking for select start
-     * and select group.star for the group of this element symbol.
-     * ElementSymbol is assumed to be fully resolved.
-     * @param elementSymbol fully resolved ElementSymbol
-     * @return whether this select will select the element symbol
-     */
-    public boolean isElementBeingSelected(ElementSymbol elementSymbol){
-        boolean isBeingSelected = this.containsSymbol(elementSymbol);
-        if (!isBeingSelected){
-            GroupSymbol g = elementSymbol.getGroupSymbol();
-            String groupDotStarName = g.getName() + ".*"; //$NON-NLS-1$
-            Iterator i = this.getSymbols().iterator();
-            while (i.hasNext()) {
-                Object selectSymbol = i.next();
-                if (selectSymbol instanceof AllSymbol){
-                    isBeingSelected = true;
-                    break;
-                } else if (selectSymbol instanceof AllInGroupSymbol){
-                    AllInGroupSymbol aigSymbol = (AllInGroupSymbol)selectSymbol;
-                    if (aigSymbol.getName().equalsIgnoreCase(groupDotStarName)){
-                        isBeingSelected = true;
-                        break;
-                    }
-                }
-            }
-        }
-        return isBeingSelected;
-    }
-    
-
 	/**
 	 * Set whether select is distinct.
 	 * @param isDistinct True if SELECT is distinct
@@ -199,17 +181,17 @@
 	 * single column.
 	 * @return Ordered list of SingleElementSymbol
 	 */
-	public List getProjectedSymbols() { 
-		ArrayList projectedSymbols = new ArrayList();
-		Iterator iter = symbols.iterator();
-		while(iter.hasNext()) {
-			SelectSymbol symbol = (SelectSymbol) iter.next();
-			if(symbol instanceof SingleElementSymbol) { 
-				projectedSymbols.add(symbol);
+	public List<DerivedColumn> getProjectedSymbols() { 
+		ArrayList<DerivedColumn> projectedSymbols = new ArrayList<DerivedColumn>();
+		for (SelectSymbol symbol : symbols) {
+			if(symbol instanceof DerivedColumn) { 
+				projectedSymbols.add((DerivedColumn)symbol);
 			} else {
-			    List multiSymbols = ((MultipleElementSymbol)symbol).getElementSymbols();
+			    List<ElementSymbol> multiSymbols = ((MultipleElementSymbol)symbol).getElementSymbols();
 			    if(multiSymbols != null) { 
-			        projectedSymbols.addAll(multiSymbols);
+			        for (ElementSymbol elementSymbol : multiSymbols) {
+						projectedSymbols.add(new DerivedColumn(elementSymbol));
+					}
 			    }
 			}	
 		}		

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -36,10 +36,8 @@
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.resolver.util.ResolverUtil;
 import com.metamatrix.query.sql.LanguageVisitor;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 
 /**
  * This object acts as a Set operator on multiple Queries - UNION,
@@ -119,40 +117,28 @@
 	 * single column.
 	 * @return Ordered list of SingleElementSymbol
 	 */
-	public List getProjectedSymbols() {
+	public List<DerivedColumn> getProjectedSymbols() {
 	    Query query = getProjectedQuery();
-	    List projectedSymbols = query.getProjectedSymbols();
+	    List<DerivedColumn> projectedSymbols = query.getProjectedSymbols();
         if (projectedTypes != null) {
             return getTypedProjectedSymbols(projectedSymbols, projectedTypes);
         } 
         return projectedSymbols;
     }
     
-    public static List getTypedProjectedSymbols(List acutal, List projectedTypes) {
-        List newProject = new ArrayList();
+    public static List<DerivedColumn> getTypedProjectedSymbols(List<DerivedColumn> acutal, List projectedTypes) {
+        List<DerivedColumn> newProject = new ArrayList<DerivedColumn>();
         for (int i = 0; i < acutal.size(); i++) {
-            SingleElementSymbol originalSymbol = (SingleElementSymbol)acutal.get(i);
-            SingleElementSymbol symbol = originalSymbol;
+            DerivedColumn symbol = acutal.get(i);
             Class type = (Class)projectedTypes.get(i);
             if (symbol.getType() != type) {
-                if (symbol instanceof AliasSymbol) {
-                    symbol = ((AliasSymbol)symbol).getSymbol();
-                } 
-
-                Expression expr = symbol;
-                if (symbol instanceof ExpressionSymbol) {
-                    expr = ((ExpressionSymbol)symbol).getExpression();
-                } 
+                Expression expr = symbol.getExpression();
                 
                 try {
-                    symbol = new ExpressionSymbol(originalSymbol.getShortName(), ResolverUtil.convertExpression(expr, DataTypeManager.getDataTypeName(type)));
+                    symbol = new DerivedColumn(symbol.getShortName(), ResolverUtil.convertExpression(expr, DataTypeManager.getDataTypeName(type)), true);
                 } catch (QueryResolverException err) {
                     throw new MetaMatrixRuntimeException(err);
                 }
-                
-                if (!(originalSymbol instanceof ExpressionSymbol)) {
-                    symbol = new AliasSymbol(originalSymbol.getShortName(), symbol);
-                } 
             }
             newProject.add(symbol);
         }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Update.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Update.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/lang/Update.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -34,7 +34,7 @@
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 import com.metamatrix.query.sql.visitor.SQLStringVisitor;
 
 /**
@@ -266,7 +266,7 @@
         for (Iterator iter = getChangeList().getClauses().iterator(); iter.hasNext();) {
         	SetClause setClause = (SetClause)iter.next();
             ElementSymbol symbol = (ElementSymbol)(setClause.getSymbol()).clone();
-            symbol.setName(ProcedureReservedWords.INPUT + SingleElementSymbol.SEPARATOR + symbol.getShortCanonicalName());
+            symbol.setName(ProcedureReservedWords.INPUT + Symbol.SEPARATOR + symbol.getShortCanonicalName());
             map.put( symbol, setClause.getValue() );
             
         } // for

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/navigator/PreOrPostOrderNavigator.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/navigator/PreOrPostOrderNavigator.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -50,6 +50,7 @@
 import com.metamatrix.query.sql.lang.NotCriteria;
 import com.metamatrix.query.sql.lang.Option;
 import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.SPParameter;
 import com.metamatrix.query.sql.lang.Select;
@@ -78,15 +79,14 @@
 import com.metamatrix.query.sql.proc.RaiseErrorStatement;
 import com.metamatrix.query.sql.proc.TranslateCriteria;
 import com.metamatrix.query.sql.proc.WhileStatement;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
@@ -122,16 +122,11 @@
     }
 
     
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         preVisitVisitor(obj);
         visitNode(obj.getExpression());
         postVisitVisitor(obj);
     }
-    public void visit(AliasSymbol obj) {
-        preVisitVisitor(obj);
-        visitNode(obj.getSymbol());
-        postVisitVisitor(obj);
-    }
     public void visit(AllInGroupSymbol obj) {
         preVisitVisitor(obj);
         postVisitVisitor(obj);
@@ -237,7 +232,7 @@
         preVisitVisitor(obj);
         postVisitVisitor(obj);        
     }
-    public void visit(ExpressionSymbol obj) {
+    public void visit(DerivedColumn obj) {
         preVisitVisitor(obj);
         visitNode(obj.getExpression());
         postVisitVisitor(obj);
@@ -360,9 +355,15 @@
     }
     public void visit(OrderBy obj) {
         preVisitVisitor(obj);
-        visitNodes(obj.getVariables());
+        visitNodes(obj.getSortOrder());
         postVisitVisitor(obj);
     }
+    @Override
+    public void visit(OrderByItem obj) {
+        preVisitVisitor(obj);
+        visitNode(obj.getSortKey());
+        postVisitVisitor(obj);
+    }
     public void visit(Query obj) {
         preVisitVisitor(obj);
         visitNode(obj.getSelect());

Copied: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Aggregate.java (from rev 529, branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AggregateSymbol.java)
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Aggregate.java	                        (rev 0)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Aggregate.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -0,0 +1,217 @@
+/*
+ * 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 com.metamatrix.query.sql.symbol;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.core.util.EquivalenceUtil;
+import com.metamatrix.core.util.HashCodeUtil;
+import com.metamatrix.query.QueryPlugin;
+import com.metamatrix.query.sql.LanguageVisitor;
+import com.metamatrix.query.sql.ReservedWords;
+import com.metamatrix.query.util.ErrorMessageKeys;
+
+/**
+ * <p>An aggregate represents an aggregate function in the SELECT or HAVING clauses, 
+ * typically something like <code>SUM(stock.quantity * 2)</code>.  There are five supported
+ * aggregate functions: COUNT, SUM, AVG, MIN, and MAX.  Aggregate functions may also
+ * specify a DISTINCT flag to indicate that duplicates should be ignored.  The DISTINCT flag
+ * may be set for all five aggregate functions but is ignored for the computation of MIN and MAX.
+ * One special use of an aggregate is for <code>COUNT(*)</code>.  The * expression
+ * is encoded by setting the expression to null.  This may ONLY be used with the COUNT function.</p>
+ *
+ * <p>The type of an aggregate depends on the function and the type of the underlying
+ * expression.  The type of a COUNT function is ALWAYS integer.  MIN and MAX functions take the
+ * type of their contained expression.  AVG and SUM vary depending on the type of the expression.
+ * If the expression is of a type other than biginteger, the aggregate function returns type long.
+ * For the case of biginteger, the aggregate function returns type biginteger.  Similarly, all
+ * floating point expressions not of type bigdecimal return type double and bigdecimal maps to
+ * bigdecimal.</p>
+ */
+public class Aggregate implements Expression {
+
+	private Expression expression;
+	private String aggregate;
+	private boolean distinct;
+
+	private static final Class COUNT_TYPE = DataTypeManager.getDataTypeClass(DataTypeManager.DefaultDataTypes.INTEGER);
+	private static final Set AGGREGATE_FUNCTIONS;
+	private static final Map SUM_TYPES;
+    private static final Map AVG_TYPES;
+
+	static {
+		AGGREGATE_FUNCTIONS = new HashSet();
+		AGGREGATE_FUNCTIONS.add(ReservedWords.COUNT);
+		AGGREGATE_FUNCTIONS.add(ReservedWords.SUM);
+		AGGREGATE_FUNCTIONS.add(ReservedWords.AVG);
+		AGGREGATE_FUNCTIONS.add(ReservedWords.MIN);
+		AGGREGATE_FUNCTIONS.add(ReservedWords.MAX);
+
+		SUM_TYPES = new HashMap();
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.BYTE, DataTypeManager.DefaultDataClasses.LONG);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.LONG);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.LONG);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.LONG, DataTypeManager.DefaultDataClasses.LONG);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_INTEGER, DataTypeManager.DefaultDataClasses.BIG_INTEGER);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.FLOAT, DataTypeManager.DefaultDataClasses.DOUBLE);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.DOUBLE, DataTypeManager.DefaultDataClasses.DOUBLE);
+		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_DECIMAL, DataTypeManager.DefaultDataClasses.BIG_DECIMAL);
+        
+        AVG_TYPES = new HashMap();
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.BYTE, DataTypeManager.DefaultDataClasses.DOUBLE);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.DOUBLE);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.DOUBLE);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.LONG, DataTypeManager.DefaultDataClasses.DOUBLE);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_INTEGER, DataTypeManager.DefaultDataClasses.BIG_DECIMAL);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.FLOAT, DataTypeManager.DefaultDataClasses.DOUBLE);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.DOUBLE, DataTypeManager.DefaultDataClasses.DOUBLE);
+        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_DECIMAL, DataTypeManager.DefaultDataClasses.BIG_DECIMAL);        
+	}
+
+	/**
+	 * Construct an aggregate with all given data.
+	 * @param aggregateFunction Aggregate function type ({@link com.metamatrix.query.sql.ReservedWords#COUNT}, etc)
+	 * @param isDistinct True if DISTINCT flag is set
+	 * @param expression Contained expression
+	 */
+	public Aggregate(String aggregateFunction, boolean isDistinct, Expression expression) {
+		this.expression = expression;
+		setAggregateFunction(aggregateFunction);
+		this.distinct = isDistinct;
+	}
+
+	/**
+	 * Set the aggregate function.  If the aggregate function is an invalid value, an
+	 * IllegalArgumentException is thrown.
+	 * @param aggregateFunction Aggregate function type
+	 * @see com.metamatrix.query.sql.ReservedWords#COUNT
+	 * @see com.metamatrix.query.sql.ReservedWords#SUM
+	 * @see com.metamatrix.query.sql.ReservedWords#AVG
+	 * @see com.metamatrix.query.sql.ReservedWords#MIN
+	 * @see com.metamatrix.query.sql.ReservedWords#MAX
+	 */
+	private void setAggregateFunction(String aggregateFunction) {
+		// Validate aggregate
+		if(! AGGREGATE_FUNCTIONS.contains(aggregateFunction)) {
+            throw new IllegalArgumentException(QueryPlugin.Util.getString(ErrorMessageKeys.SQL_0013, new Object[] {aggregateFunction, AGGREGATE_FUNCTIONS}));
+		}
+		this.aggregate = aggregateFunction;
+	}
+
+	/**
+	 * Get the aggregate function type - this will map to one of the reserved words
+	 * for the aggregate functions.
+	 * @return Aggregate function type
+	 * @see com.metamatrix.query.sql.ReservedWords#COUNT
+	 * @see com.metamatrix.query.sql.ReservedWords#SUM
+	 * @see com.metamatrix.query.sql.ReservedWords#AVG
+	 * @see com.metamatrix.query.sql.ReservedWords#MIN
+	 * @see com.metamatrix.query.sql.ReservedWords#MAX
+	 */
+	public String getAggregateFunction() {
+		return this.aggregate;
+	}
+
+	/**
+	 * Get the distinct flag.  If true, aggregate will remove duplicates during
+	 * computation.
+	 * @return True if duplicates should be removed during computation
+	 */
+	public boolean isDistinct() {
+		return this.distinct;
+	}
+
+	/**
+	 * Get the type of the aggregate, which depends on the aggregate function and the
+	 * type of the contained expression
+	 */
+	public Class getType() {
+		if(this.aggregate.equals(ReservedWords.COUNT)) {
+			return COUNT_TYPE;
+		} else if(this.aggregate.equals(ReservedWords.SUM) ) {
+			Class expressionType = this.getExpression().getType();
+			return (Class) SUM_TYPES.get(expressionType);
+        } else if (this.aggregate.equals(ReservedWords.AVG)) {
+            Class expressionType = this.getExpression().getType();
+            return (Class) AVG_TYPES.get(expressionType);
+		} else {
+			return this.getExpression().getType();
+		}
+	}
+
+    public void acceptVisitor(LanguageVisitor visitor) {
+        visitor.visit(this);
+    }
+
+	/**
+	 * Return a deep copy of this object
+	 */
+	public Object clone() {
+		Aggregate copy = null;
+		if(getExpression() != null) {
+			copy = new Aggregate(getAggregateFunction(), isDistinct(), (Expression) getExpression().clone());
+		} else {
+			copy = new Aggregate(getAggregateFunction(), isDistinct(), null);
+		}
+
+		return copy;
+	}
+	
+	public Expression getExpression() {
+		return expression;
+	}
+	
+	public void setExpression(Expression expression) {
+		this.expression = expression;
+	}
+	
+	@Override
+	public boolean isResolved() {
+		if (this.expression != null) {
+			return this.expression.isResolved();
+		}
+		return true;
+	}
+    
+    public int hashCode() {
+        int hasCode = HashCodeUtil.hashCode(aggregate.hashCode(), distinct);
+        return HashCodeUtil.hashCode(hasCode, this.getExpression());
+    }
+    
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Aggregate)) {
+            return false;
+        }
+        
+        Aggregate other = (Aggregate)obj;
+        
+        return this.aggregate.equals(other.aggregate)
+               && this.distinct == other.distinct
+               && EquivalenceUtil.areEqual(this.getExpression(), other.getExpression());
+    }
+
+}


Property changes on: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Aggregate.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AggregateSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AggregateSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AggregateSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -1,224 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership.  Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package com.metamatrix.query.sql.symbol;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import com.metamatrix.common.types.DataTypeManager;
-import com.metamatrix.core.util.EquivalenceUtil;
-import com.metamatrix.core.util.HashCodeUtil;
-import com.metamatrix.query.QueryPlugin;
-import com.metamatrix.query.sql.LanguageVisitor;
-import com.metamatrix.query.sql.ReservedWords;
-import com.metamatrix.query.util.ErrorMessageKeys;
-
-/**
- * <p>An aggregate symbol represents an aggregate function in the SELECT or HAVING clauses.  It
- * extends ExpressionSymbol as they have many things in common.  The aggregate symbol is
- * typically something like <code>SUM(stock.quantity * 2)</code>.  There are five supported
- * aggregate functions: COUNT, SUM, AVG, MIN, and MAX.  Aggregate functions contain an expression -
- * this data is managed by the super class, ExpressionSymbol.  Aggregate functions may also
- * specify a DISTINCT flag to indicate that duplicates should be ignored.  The DISTINCT flag
- * may be set for all five aggregate functions but is ignored for the computation of MIN and MAX.
- * One special use of an aggregate symbol is for the symbol <code>COUNT(*)</code>.  The * expression
- * is encoded by setting the expression to null.  This may ONLY be used with the COUNT function.</p>
- *
- * <p>The type of an aggregate symbol depends on the function and the type of the underlying
- * expression.  The type of a COUNT function is ALWAYS integer.  MIN and MAX functions take the
- * type of their contained expression.  AVG and SUM vary depending on the type of the expression.
- * If the expression is of a type other than biginteger, the aggregate function returns type long.
- * For the case of biginteger, the aggregate function returns type biginteger.  Similarly, all
- * floating point expressions not of type bigdecimal return type double and bigdecimal maps to
- * bigdecimal.</p>
- */
-public class AggregateSymbol extends ExpressionSymbol {
-
-	private String aggregate;
-	private boolean distinct;
-
-	private static final Class COUNT_TYPE = DataTypeManager.getDataTypeClass(DataTypeManager.DefaultDataTypes.INTEGER);
-	private static final Set AGGREGATE_FUNCTIONS;
-	private static final Map SUM_TYPES;
-    private static final Map AVG_TYPES;
-
-	static {
-		AGGREGATE_FUNCTIONS = new HashSet();
-		AGGREGATE_FUNCTIONS.add(ReservedWords.COUNT);
-		AGGREGATE_FUNCTIONS.add(ReservedWords.SUM);
-		AGGREGATE_FUNCTIONS.add(ReservedWords.AVG);
-		AGGREGATE_FUNCTIONS.add(ReservedWords.MIN);
-		AGGREGATE_FUNCTIONS.add(ReservedWords.MAX);
-
-		SUM_TYPES = new HashMap();
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.BYTE, DataTypeManager.DefaultDataClasses.LONG);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.LONG);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.LONG);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.LONG, DataTypeManager.DefaultDataClasses.LONG);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_INTEGER, DataTypeManager.DefaultDataClasses.BIG_INTEGER);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.FLOAT, DataTypeManager.DefaultDataClasses.DOUBLE);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.DOUBLE, DataTypeManager.DefaultDataClasses.DOUBLE);
-		SUM_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_DECIMAL, DataTypeManager.DefaultDataClasses.BIG_DECIMAL);
-        
-        AVG_TYPES = new HashMap();
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.BYTE, DataTypeManager.DefaultDataClasses.DOUBLE);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.DOUBLE);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.DOUBLE);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.LONG, DataTypeManager.DefaultDataClasses.DOUBLE);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_INTEGER, DataTypeManager.DefaultDataClasses.BIG_DECIMAL);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.FLOAT, DataTypeManager.DefaultDataClasses.DOUBLE);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.DOUBLE, DataTypeManager.DefaultDataClasses.DOUBLE);
-        AVG_TYPES.put(DataTypeManager.DefaultDataClasses.BIG_DECIMAL, DataTypeManager.DefaultDataClasses.BIG_DECIMAL);        
-	}
-
-    /**
-     * Constructor used for cloning 
-     * @param name
-     * @param canonicalName
-     * @since 4.3
-     */
-    protected AggregateSymbol(String name, String canonicalName, String aggregateFunction, boolean isDistinct, Expression expression) {
-        super(name, canonicalName, expression);
-        
-        setAggregateFunction(aggregateFunction);
-        this.distinct = isDistinct;
-    }
-    
-	/**
-	 * Construct an aggregate symbol with all given data.
-	 * @param name Name of the function
-	 * @param aggregateFunction Aggregate function type ({@link com.metamatrix.query.sql.ReservedWords#COUNT}, etc)
-	 * @param isDistinct True if DISTINCT flag is set
-	 * @param expression Contained expression
-	 */
-	public AggregateSymbol(String name, String aggregateFunction, boolean isDistinct, Expression expression) {
-		super(name, expression);
-
-		setAggregateFunction(aggregateFunction);
-		this.distinct = isDistinct;
-	}
-
-	/**
-	 * Set the aggregate function.  If the aggregate function is an invalid value, an
-	 * IllegalArgumentException is thrown.
-	 * @param aggregateFunction Aggregate function type
-	 * @see com.metamatrix.query.sql.ReservedWords#COUNT
-	 * @see com.metamatrix.query.sql.ReservedWords#SUM
-	 * @see com.metamatrix.query.sql.ReservedWords#AVG
-	 * @see com.metamatrix.query.sql.ReservedWords#MIN
-	 * @see com.metamatrix.query.sql.ReservedWords#MAX
-	 */
-	private void setAggregateFunction(String aggregateFunction) {
-		// Validate aggregate
-		if(! AGGREGATE_FUNCTIONS.contains(aggregateFunction)) {
-            throw new IllegalArgumentException(QueryPlugin.Util.getString(ErrorMessageKeys.SQL_0013, new Object[] {aggregateFunction, AGGREGATE_FUNCTIONS}));
-		}
-		this.aggregate = aggregateFunction;
-	}
-
-	/**
-	 * Get the aggregate function type - this will map to one of the reserved words
-	 * for the aggregate functions.
-	 * @return Aggregate function type
-	 * @see com.metamatrix.query.sql.ReservedWords#COUNT
-	 * @see com.metamatrix.query.sql.ReservedWords#SUM
-	 * @see com.metamatrix.query.sql.ReservedWords#AVG
-	 * @see com.metamatrix.query.sql.ReservedWords#MIN
-	 * @see com.metamatrix.query.sql.ReservedWords#MAX
-	 */
-	public String getAggregateFunction() {
-		return this.aggregate;
-	}
-
-	/**
-	 * Get the distinct flag.  If true, aggregate symbol will remove duplicates during
-	 * computation.
-	 * @return True if duplicates should be removed during computation
-	 */
-	public boolean isDistinct() {
-		return this.distinct;
-	}
-
-	/**
-	 * Get the type of the symbol, which depends on the aggregate function and the
-	 * type of the contained expression
-	 * @return Type of the symbol
-	 */
-	public Class getType() {
-		if(this.aggregate.equals(ReservedWords.COUNT)) {
-			return COUNT_TYPE;
-		} else if(this.aggregate.equals(ReservedWords.SUM) ) {
-			Class expressionType = this.getExpression().getType();
-			return (Class) SUM_TYPES.get(expressionType);
-        } else if (this.aggregate.equals(ReservedWords.AVG)) {
-            Class expressionType = this.getExpression().getType();
-            return (Class) AVG_TYPES.get(expressionType);
-		} else {
-			return this.getExpression().getType();
-		}
-	}
-
-    public void acceptVisitor(LanguageVisitor visitor) {
-        visitor.visit(this);
-    }
-
-	/**
-	 * Return a deep copy of this object
-	 */
-	public Object clone() {
-		AggregateSymbol copy = null;
-		if(getExpression() != null) {
-			copy = new AggregateSymbol(getName(), getCanonical(), getAggregateFunction(), isDistinct(), (Expression) getExpression().clone());
-		} else {
-			copy = new AggregateSymbol(getName(), getCanonical(), getAggregateFunction(), isDistinct(), null);
-		}
-
-		return copy;
-	}
-    
-    /** 
-     * @see com.metamatrix.query.sql.symbol.ExpressionSymbol#hashCode()
-     */
-    public int hashCode() {
-        int hasCode = HashCodeUtil.hashCode(aggregate.hashCode(), distinct);
-        return HashCodeUtil.hashCode(hasCode, this.getExpression());
-    }
-    
-    /** 
-     * @see com.metamatrix.query.sql.symbol.ExpressionSymbol#equals(java.lang.Object)
-     */
-    public boolean equals(Object obj) {
-        if (!(obj instanceof AggregateSymbol)) {
-            return false;
-        }
-        
-        AggregateSymbol other = (AggregateSymbol)obj;
-        
-        return this.aggregate.equals(other.aggregate)
-               && this.distinct == other.distinct
-               && EquivalenceUtil.areEqual(this.getExpression(), other.getExpression());
-    }
-
-}

Deleted: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AliasSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AliasSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/AliasSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -1,131 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership.  Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package com.metamatrix.query.sql.symbol;
-
-import com.metamatrix.core.util.Assertion;
-import com.metamatrix.query.QueryPlugin;
-import com.metamatrix.query.sql.LanguageVisitor;
-import com.metamatrix.query.util.ErrorMessageKeys;
-
-/**
- * An AliasSymbol wraps a SingleElementSymbol and changes it's name.  AliasSymbols
- * should be used to perform the aliasing of elements in a SELECT clause.  They
- * should typically NOT be used elsewhere in a query.  The alias symbol takes on
- * the type of it's underlying SingleElementSymbol.  AliasSymbols are typically
- * applied to ElementSymbol, ExpressionSymbol, and AggregateSymbol.
- */
-public class AliasSymbol extends SingleElementSymbol {
-
-	private SingleElementSymbol symbol;
-
-    /**
-     * Constructor used for cloning 
-     * @param name
-     * @param canonicalName
-     * @since 4.3
-     */
-    private AliasSymbol(String name, String canonicalName, SingleElementSymbol symbol) {
-        super(name, canonicalName);
-        setSymbol(symbol);
-    }
-    
-	/**
-	 * Construct an AliasSymbol given the alias name and the underlying symbol.
-	 * @param name Name of the alias
-	 * @param symbol Underlying symbol
-	 */
-	public AliasSymbol(String name, SingleElementSymbol symbol) {
-		super(name);
-		setSymbol(symbol);
-	}
-
-	/**
-	 * Get the underlying symbol
-	 * @return Underlying symbol
-	 */
-	public SingleElementSymbol getSymbol() {
-		return this.symbol;
-	}
-
-	/**
-	 * Set the underlying symbol
-	 * @param symbol New symbol
-	 */
-	public void setSymbol(SingleElementSymbol symbol) {
-        if(symbol instanceof AliasSymbol || symbol == null){
-            Assertion.failed(QueryPlugin.Util.getString(ErrorMessageKeys.SQL_0029));
-        }
-		this.symbol = symbol;
-	}
-
-	/**
-	 * Get the type of the symbol
-	 * @return Type of the symbol
-	 */
-	public Class getType() {
-		return this.symbol.getType();
-	}
-
-	/**
-	 * Returns true if this symbol has been completely resolved with respect
-	 * to actual runtime metadata.  A resolved symbol has been validated that
-	 * it refers to actual metadata and will have references to the real metadata
-	 * IDs if necessary.  Different types of symbols determine their resolution
-	 * in different ways, so this method is abstract and must be implemented
-	 * by subclasses.
-	 * @return True if resolved with runtime metadata
-	 */
-	public boolean isResolved() {
-		return this.symbol.isResolved();
-	}
-
-    public void acceptVisitor(LanguageVisitor visitor) {
-        visitor.visit(this);
-    }
-
-	/**
-	 * Return a copy of this object.
-	 */
-	public Object clone() {
-		SingleElementSymbol symbolCopy = (SingleElementSymbol) this.symbol.clone();
-		AliasSymbol result = new AliasSymbol(getName(), getCanonical(), symbolCopy);
-		result.setOutputName(this.getOutputName());
-		return result;
-	}
-	
-   /** 
-     * @see com.metamatrix.query.sql.symbol.Symbol#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof AliasSymbol)) {
-            return false;
-        }
-        AliasSymbol other = (AliasSymbol)obj;
-        return this.getCanonicalName().equals(other.getCanonicalName()) && this.symbol.equals(other.symbol);
-    }
-
-}

Copied: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/DerivedColumn.java (from rev 529, branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ExpressionSymbol.java)
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/DerivedColumn.java	                        (rev 0)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/DerivedColumn.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -0,0 +1,155 @@
+/*
+ * 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 com.metamatrix.query.sql.symbol;
+
+import com.metamatrix.query.sql.LanguageVisitor;
+
+/**
+ * <p>This is a subclass of Symbol representing an expression in the SELECT clause.  The
+ * expression may be a constant, function, or scalar subquery.</p>
+ */
+public class DerivedColumn extends SelectSymbol {
+	private Expression expression;
+	private boolean alias;
+
+    /**
+     * Constructor used for cloning 
+     * @param name
+     * @param canonicalName
+     * @since 4.3
+     */
+    protected DerivedColumn(String name, String canonicalName, Expression expression) {
+        super(name, canonicalName);
+        this.expression = expression;
+    }
+    
+    public DerivedColumn(ElementSymbol symbol) {
+    	this(symbol.getName(), symbol.getCanonical(), symbol);
+    }
+    
+    /**
+     * Construct an ExpressionSymbol with name and expression.
+     */
+    public DerivedColumn(String name, Expression expression) {
+    	this(name, expression, false);
+    }
+    
+    public DerivedColumn(String name, Expression expression, boolean alias) {
+        super(name);
+		this.expression = expression;
+		this.alias = alias;
+    }
+
+   
+	/**
+	 * Get the expression for this symbol
+	 * @return Expression for this symbol
+	 */
+	public Expression getExpression() {
+		return this.expression;
+	}
+	
+	/**
+  	 * Set the expression represented by this symbol.
+  	 * @param expression Expression for this expression symbol
+ 	 */
+	public void setExpression(Expression expression) {
+		this.expression = expression;
+	}
+
+	/**
+	 * Get the type of the symbol
+	 * @return Type of the symbol, may be null before resolution
+	 */
+	public Class getType() {
+		return this.expression.getType();
+	}	
+	
+    public void acceptVisitor(LanguageVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    /**
+     * If elementSymbols is not null return true, else return false
+     * @return boolean True if expression symbol has been resolved to element symbols
+     */
+    public boolean isResolved() {
+        return true;
+    }
+
+	/**
+	 * Return a deep copy of this object
+	 * @return Deep copy of this object
+	 */
+	public Object clone() {
+	    Expression clonedExpr = null;
+	    if(getExpression() != null) { 
+			clonedExpr = (Expression) getExpression().clone();		
+	    }
+	    DerivedColumn copy = new DerivedColumn(getName(), getCanonical(), clonedExpr);
+	    copy.setAlias(this.alias);
+	    return copy;
+	}
+
+    public boolean isAlias() {
+		return alias;
+	}
+    
+    public void setAlias(boolean alias) {
+		this.alias = alias;
+	}
+    
+    /** 
+     * @see com.metamatrix.query.sql.symbol.Symbol#hashCode()
+     */
+    public int hashCode() {
+        if (expression != null) {
+            return expression.hashCode();
+        }
+        return super.hashCode();
+    }
+    
+    /** 
+     * ExpressionSymbol matching is not based upon the name
+     * 
+     * @see com.metamatrix.query.sql.symbol.Symbol#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        
+        if (!(obj instanceof DerivedColumn)) {
+            return false;
+        }
+        
+        DerivedColumn exprSymbol = (DerivedColumn)obj;
+        
+        if (expression == null ) {
+            return exprSymbol.getExpression() == null;
+        }
+        
+        return expression.equals(exprSymbol.getExpression());
+    }
+        	
+}


Property changes on: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/DerivedColumn.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ElementSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ElementSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ElementSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -35,7 +35,7 @@
  * is set to false.  Common uses when this is set to true are for variables used 
  * within a command, correlated elements within a command, etc. </p>
  */
-public class ElementSymbol extends SingleElementSymbol {
+public class ElementSymbol extends Symbol implements Expression {
 
     public enum DisplayMode {
         FULLY_QUALIFIED, // symbol name 

Deleted: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ExpressionSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ExpressionSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/ExpressionSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -1,150 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership.  Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package com.metamatrix.query.sql.symbol;
-
-import com.metamatrix.query.sql.*;
-
-/**
- * <p>This is a subclass of Symbol representing an expression in the SELECT clause.  The
- * expression may be a constant, function, or scalar subquery.  The name of this symbol is always generated
- * and typically should not be displayed.  If necessary, the ExpressionSymbol may be 
- * wrapped by an AliasSymbol to register the name in a query.  The definition of the 
- * symbol is the functional expression.  Resolution will produce a list of groups and 
- * elements used by the expression.</p>
- */
-public class ExpressionSymbol extends SingleElementSymbol {
-	private Expression expression;
-	private boolean derivedExpression;
-
-    /**
-     * Constructor used for cloning 
-     * @param name
-     * @param canonicalName
-     * @since 4.3
-     */
-    protected ExpressionSymbol(String name, String canonicalName, Expression expression) {
-        super(name, canonicalName);
-        this.expression = expression;
-    }
-    
-    /**
-     * Construct an ExpressionSymbol with name and expression.
-     */
-    public ExpressionSymbol(String name, Expression expression) {
-        super(name);
-		this.expression = expression;
-    }
-
-	/**
-	 * Get the expression for this symbol
-	 * @return Expression for this symbol
-	 */
-	public Expression getExpression() {
-		return this.expression;
-	}
-	
-	/**
-  	 * Set the expression represented by this symbol.
-  	 * @param expression Expression for this expression symbol
- 	 */
-	public void setExpression(Expression expression) {
-		this.expression = expression;
-	}
-
-	/**
-	 * Get the type of the symbol
-	 * @return Type of the symbol, may be null before resolution
-	 */
-	public Class getType() {
-		return this.expression.getType();
-	}	
-	
-    public void acceptVisitor(LanguageVisitor visitor) {
-        visitor.visit(this);
-    }
-
-    /**
-     * If elementSymbols is not null return true, else return false
-     * @return boolean True if expression symbol has been resolved to element symbols
-     */
-    public boolean isResolved() {
-        return true;
-    }
-
-	/**
-	 * Return a deep copy of this object
-	 * @return Deep copy of this object
-	 */
-	public Object clone() {
-	    Expression clonedExpr = null;
-	    if(getExpression() != null) { 
-			clonedExpr = (Expression) getExpression().clone();		
-	    }
-	    ExpressionSymbol copy = new ExpressionSymbol(getName(), getCanonical(), clonedExpr);
-	    copy.setDerivedExpression(this.derivedExpression);
-	    return copy;
-	}
-
-    public boolean isDerivedExpression() {
-        return this.derivedExpression;
-    }
-
-    public void setDerivedExpression(boolean derivedExpression) {
-        this.derivedExpression = derivedExpression;
-    }
-    
-    
-    /** 
-     * @see com.metamatrix.query.sql.symbol.Symbol#hashCode()
-     */
-    public int hashCode() {
-        if (expression != null) {
-            return expression.hashCode();
-        }
-        return super.hashCode();
-    }
-    
-    /** 
-     * ExpressionSymbol matching is not based upon the name
-     * 
-     * @see com.metamatrix.query.sql.symbol.Symbol#equals(java.lang.Object)
-     */
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        
-        if (!(obj instanceof ExpressionSymbol)) {
-            return false;
-        }
-        
-        ExpressionSymbol exprSymbol = (ExpressionSymbol)obj;
-        
-        if (expression == null ) {
-            return exprSymbol.getExpression() == null;
-        }
-        
-        return expression.equals(exprSymbol.getExpression());
-    }
-        	
-}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/MultipleElementSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/MultipleElementSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/MultipleElementSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -28,7 +28,7 @@
  * <p>This is a subclass of Symbol representing multiple output columns.</p>
  */
 public abstract class MultipleElementSymbol extends SelectSymbol {
-    private List elementSymbols;
+    private List<ElementSymbol> elementSymbols;
 
     /**
      * Passthrough constructor used for cloning 
@@ -52,7 +52,7 @@
      * Set the {@link ElementSymbol}s that this symbol refers to
      * @param elementSymbols List of {@link ElementSymbol}
      */
-    public void setElementSymbols(List elementSymbols){
+    public void setElementSymbols(List<ElementSymbol> elementSymbols){
         this.elementSymbols = elementSymbols;
     }
 
@@ -60,7 +60,7 @@
      * Get the element symbols referred to by this multiple element symbol
      * @return List of {@link ElementSymbol}s, may be null
      */
-    public List getElementSymbols(){
+    public List<ElementSymbol> getElementSymbols(){
         return this.elementSymbols;
     }
 
@@ -70,7 +70,7 @@
      */
     public void addElementSymbol(ElementSymbol symbol) {
 		if(getElementSymbols() == null) { 
-			setElementSymbols(new LinkedList());
+			setElementSymbols(new LinkedList<ElementSymbol>());
 		}
 		getElementSymbols().add(symbol);
     }

Deleted: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/SingleElementSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/SingleElementSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/SingleElementSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -1,81 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership.  Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package com.metamatrix.query.sql.symbol;
-
-
-
-/**
- * <p>This is a subclass of Symbol representing a single output column.</p>
- */
-public abstract class SingleElementSymbol extends SelectSymbol implements Expression {
-
-	/**
-     * Character used to delimit name components in a symbol
-	 */
-    public static final String SEPARATOR = "."; //$NON-NLS-1$
-
-    /**
-     * Passthrough constructor used for cloning 
-     * @param name
-     * @param canonicalName
-     * @param hashcode
-     * @since 4.3
-     */
-    protected SingleElementSymbol(String name, String canonicalName) {
-        super(name, canonicalName);
-    }
-    
-    /**
-     * Construct a symbol with a name
-     * @param name Name of symbol
-     */
-    public SingleElementSymbol(String name){
-        super(name);
-    }
-
-    /**
-     * Get the short name of the element
-     * @return Short name of the symbol (un-dotted)
-     */
-    public String getShortName() { 
-        String name = getName();
-        return getShortName(name);
-    }
-
-    public static String getShortName(String name) {
-        int index = name.lastIndexOf(SEPARATOR);
-        if(index >= 0) { 
-            return name.substring(index+1);
-        }
-        return name;
-    }
-    
-    /**
-     * Get the short name of the element
-     * @return Short name of the symbol (un-dotted)
-     */
-    public String getShortCanonicalName() { 
-        String name = getCanonicalName();
-        return getShortName(name);
-    }
-}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Symbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Symbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/symbol/Symbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -59,6 +59,11 @@
 	 * The AliasGenerator can also set this value as necessary for the data tier.
 	 */
     private String outputName;
+
+	/**
+	 * Character used to delimit name components in a symbol
+	 */
+	public static final String SEPARATOR = "."; //$NON-NLS-1$
     
     /**
      * Constructor to be used for cloning instances. Calls to String.toUpperCase() to generate the canonical names
@@ -81,7 +86,23 @@
 	public Symbol(String name) {
 		setName(name);
 	}
+	
+    /**
+     * Get the short name of the element
+     * @return Short name of the symbol (un-dotted)
+     */
+    public String getShortName() { 
+        return Symbol.getShortName(name);
+    }
 
+    /**
+     * Get the short name of the element
+     * @return Short name of the symbol (un-dotted)
+     */
+    public String getShortCanonicalName() { 
+        return Symbol.getShortName(getCanonicalName());
+    }
+
 	/**
 	 * Change the symbol's name.  This will change the symbol's hash code
 	 * and canonical name!!!!!!!!!!!!!!!!!  If this symbol is in a hashed
@@ -188,4 +209,12 @@
         this.outputName =outputName;
     }
 
+	public static String getShortName(String name) {
+	    int index = name.lastIndexOf(Symbol.SEPARATOR);
+	    if(index >= 0) { 
+	        return name.substring(index+1);
+	    }
+	    return name;
+	}
+
 }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/SymbolMap.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/SymbolMap.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/SymbolMap.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -31,13 +31,10 @@
 import java.util.Map;
 
 import com.metamatrix.core.util.Assertion;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 
 public class SymbolMap {
 
@@ -49,25 +46,9 @@
      */
     public boolean addMapping(ElementSymbol symbol,
                               Expression expression) {
-        return map.put(symbol, getExpression(expression)) == null;
+        return map.put(symbol, expression) == null;
     }
 
-    public static final Expression getExpression(Expression symbol) {
-        if (!(symbol instanceof SingleElementSymbol)) {
-            return symbol;
-        }
-        if (symbol instanceof AliasSymbol) {
-            symbol = ((AliasSymbol)symbol).getSymbol();
-        }
-
-        if (symbol instanceof ExpressionSymbol && !(symbol instanceof AggregateSymbol)) {
-            ExpressionSymbol exprSymbol = (ExpressionSymbol)symbol;
-            return exprSymbol.getExpression();
-        }
-
-        return symbol;
-    }
-
     public Expression getMappedExpression(ElementSymbol symbol) {
         return map.get(symbol);
     }
@@ -85,16 +66,20 @@
     }
 
     public static final SymbolMap createSymbolMap(GroupSymbol virtualGroup,
-                                                  List<? extends SingleElementSymbol> projectCols) {
-        return createSymbolMap(virtualGroup, projectCols, projectCols);
+                                                  List<DerivedColumn> projectCols) {
+    	List<Expression> mappedExpressions = new ArrayList<Expression>(projectCols.size());
+    	for (DerivedColumn dc : projectCols) {
+			mappedExpressions.add(dc.getExpression());
+		}
+        return createSymbolMap(virtualGroup, projectCols, mappedExpressions);
     }
 
     public static final SymbolMap createSymbolMap(GroupSymbol virtualGroup,
-                                                  List<? extends SingleElementSymbol> projectCols,
-                                                  List<? extends SingleElementSymbol> mappedCols) {
+                                                  List<DerivedColumn> projectCols,
+                                                  List<? extends Expression> mappedCols) {
         String virtualGroupName = virtualGroup.getName();
         List<ElementSymbol> virtualElements = new LinkedList<ElementSymbol>();
-        for (SingleElementSymbol symbol : projectCols) {
+        for (DerivedColumn symbol : projectCols) {
             String name = symbol.getShortName();
             String virtualElementName = virtualGroupName + ElementSymbol.SEPARATOR + name;
             ElementSymbol virtualElement = new ElementSymbol(virtualElementName);

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/UpdateProcedureGenerator.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/UpdateProcedureGenerator.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/util/UpdateProcedureGenerator.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -75,7 +75,7 @@
 		//the command should be a query
 		Query query = (Query)queryTransformation;
 		//get a list of symbols in select statement
-		List selectSymbols = query.getProjectedSymbols();
+		List<DerivedColumn> selectSymbols = query.getProjectedSymbols();
         
         if(query.getFrom() == null) {
             return null;
@@ -159,7 +159,7 @@
      * @param variables Collect each variable (physical element being updated)
      * @param values Collect each value (INPUT value for respective virtual element)
      */
-    private static void mapElements(List physicalElements, List virtualElements, String physicalGroup, QueryMetadataInterface metadata, List variables, List values)
+    private static void mapElements(List<DerivedColumn> physicalElements, List virtualElements, String physicalGroup, QueryMetadataInterface metadata, List variables, List values)
             throws MetaMatrixComponentException, QueryMetadataException{
 
         if(physicalElements.size()!= virtualElements.size()) {
@@ -169,13 +169,10 @@
         //match the physical group elements to the virtual group elements
         for(int i=0; i<physicalElements.size(); i++) {
             // Strip alias if necessary to get physical element
-            SingleElementSymbol pSymbol = (SingleElementSymbol)physicalElements.get(i);
-            if(pSymbol instanceof AliasSymbol) {
-                pSymbol = ((AliasSymbol) pSymbol).getSymbol();
-            }
+            DerivedColumn pSymbol = physicalElements.get(i);
 
-            if(pSymbol instanceof ElementSymbol) {
-                final Object mid = ((ElementSymbol)pSymbol).getMetadataID();
+            if(pSymbol.getExpression() instanceof ElementSymbol) {
+                final Object mid = ((ElementSymbol)pSymbol.getExpression()).getMetadataID();
                 final boolean supportsUpdate = metadata.elementSupports(mid, SupportConstants.Element.UPDATE);
                 //Only include elements that are updateable.
                 if(supportsUpdate) {

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/AggregateSymbolCollectorVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/AggregateSymbolCollectorVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/AggregateSymbolCollectorVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -29,10 +29,10 @@
 import com.metamatrix.query.sql.LanguageObject;
 import com.metamatrix.query.sql.LanguageVisitor;
 import com.metamatrix.query.sql.navigator.PreOrPostOrderNavigator;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Expression;
 
 public class AggregateSymbolCollectorVisitor extends LanguageVisitor {
     
@@ -42,17 +42,17 @@
             super(visitor, PreOrPostOrderNavigator.POST_ORDER);
         }
         
-        public void visit(AggregateSymbol obj) {
+        public void visit(Aggregate obj) {
             // Visit aggregate symbol but do not dive into it's expression
             preVisitVisitor(obj);
             postVisitVisitor(obj);
         }
         
         /** 
-         * @see com.metamatrix.query.sql.navigator.PreOrPostOrderNavigator#visit(com.metamatrix.query.sql.symbol.ExpressionSymbol)
+         * @see com.metamatrix.query.sql.navigator.PreOrPostOrderNavigator#visit(com.metamatrix.query.sql.symbol.DerivedColumn)
          */
         @Override
-        public void visit(ExpressionSymbol obj) {
+        public void visit(DerivedColumn obj) {
             if (obj.isDerivedExpression()) {
                 preVisitVisitor(obj);
                 postVisitVisitor(obj);
@@ -63,23 +63,23 @@
          
     }
 
-    private Collection<AggregateSymbol> aggregates;
-    private Collection<SingleElementSymbol> groupingSymbols;
+    private Collection<Aggregate> aggregates;
+    private Collection<Expression> groupingSymbols;
     
-	public AggregateSymbolCollectorVisitor(Collection<AggregateSymbol> aggregates, Collection<SingleElementSymbol> elements) { 
+	public AggregateSymbolCollectorVisitor(Collection<Aggregate> aggregates, Collection<Expression> elements) { 
         this.aggregates = aggregates;
         this.groupingSymbols = elements;
 	}	
     
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         if (aggregates != null) {
             this.aggregates.add(obj);
         }
     }
     
-    public void visit(ExpressionSymbol obj) {
+    public void visit(DerivedColumn obj) {
         if (this.groupingSymbols != null && obj.isDerivedExpression()) {
-            this.groupingSymbols.add(obj);     
+            this.groupingSymbols.add(obj.getExpression());     
         }
     }
 
@@ -89,19 +89,19 @@
         }
     }
 
-    public static final void getAggregates(LanguageObject obj, Collection<SingleElementSymbol> aggregates, Collection<SingleElementSymbol> elements) {
-        AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(new ArrayList<AggregateSymbol>(), elements);
+    public static final void getAggregates(LanguageObject obj, Collection<Expression> aggregates, Collection<Expression> elements) {
+        AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(new ArrayList<Aggregate>(), elements);
         AggregateStopNavigator asn = new AggregateStopNavigator(visitor);
         obj.acceptVisitor(asn);
         aggregates.addAll(visitor.aggregates);
     }
 
-    public static final Collection<AggregateSymbol> getAggregates(LanguageObject obj, boolean removeDuplicates) {
-        Collection<AggregateSymbol> aggregates = null;
+    public static final Collection<Aggregate> getAggregates(LanguageObject obj, boolean removeDuplicates) {
+        Collection<Aggregate> aggregates = null;
         if (removeDuplicates) {
-            aggregates = new HashSet<AggregateSymbol>();
+            aggregates = new HashSet<Aggregate>();
         } else {
-            aggregates = new ArrayList<AggregateSymbol>();    
+            aggregates = new ArrayList<Aggregate>();    
         }
         AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(aggregates, null);
         AggregateStopNavigator asn = new AggregateStopNavigator(visitor);

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -309,9 +309,6 @@
      *         translated. Otherwise, the same expression.
      */
     private Expression replaceExpression(Expression exp) {
-        if(exp instanceof AliasSymbol) {
-            exp = ((AliasSymbol)exp).getSymbol();
-        }
         if(exp instanceof ElementSymbol) {
             exp = getTranslatedExpression((ElementSymbol)exp);
         }

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/EvaluatableVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/EvaluatableVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/EvaluatableVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -38,9 +38,9 @@
 import com.metamatrix.query.sql.lang.SubqueryCompareCriteria;
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
@@ -108,11 +108,11 @@
     	}
     }
     
-    public void visit(ExpressionSymbol obj) {
+    public void visit(DerivedColumn obj) {
         evaluationNotPossible();
     }
     
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         evaluationNotPossible();
     }
     

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -39,9 +39,8 @@
 import com.metamatrix.query.sql.lang.IsNullCriteria;
 import com.metamatrix.query.sql.lang.Limit;
 import com.metamatrix.query.sql.lang.MatchCriteria;
-import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
 import com.metamatrix.query.sql.lang.SPParameter;
-import com.metamatrix.query.sql.lang.Select;
 import com.metamatrix.query.sql.lang.SetClause;
 import com.metamatrix.query.sql.lang.SetCriteria;
 import com.metamatrix.query.sql.lang.StoredProcedure;
@@ -50,14 +49,12 @@
 import com.metamatrix.query.sql.navigator.PostOrderNavigator;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
 import com.metamatrix.query.sql.proc.AssignmentStatement;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.SearchedCaseExpression;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 
 /**
  * It is important to use a Post Navigator with this class, 
@@ -79,57 +76,14 @@
     	return true;
     }
     
-    public void visit(Select obj) {
-        replaceSymbols(obj.getSymbols(), true);
-    }
-
-    private void replaceSymbols(List symbols, boolean alias) {
-        for (int i = 0; i < symbols.size(); i++) {
-            Object symbol = symbols.get(i);
-            
-            if (symbol instanceof SingleElementSymbol) {
-                SingleElementSymbol ses = (SingleElementSymbol)symbol;
-                SingleElementSymbol replacmentSymbol = null; 
-
-                Expression expr = ses;
-                if (ses instanceof ExpressionSymbol && !(ses instanceof AggregateSymbol)) {
-                    expr = ((ExpressionSymbol)ses).getExpression();
-                }
-                
-                Expression replacement = replaceExpression(expr);
-                
-                if (replacement instanceof SingleElementSymbol) {
-                    replacmentSymbol = (SingleElementSymbol)replacement;
-                } else {
-                    replacmentSymbol = new ExpressionSymbol(ses.getName(), replacement);
-                }
-                
-                if (alias && createAliases() && !replacmentSymbol.getShortName().equals(ses.getShortName())) {
-                    replacmentSymbol = new AliasSymbol(ses.getShortName(), replacmentSymbol);
-                }
-                
-                symbols.set(i, replacmentSymbol);
-            }
+    public void visit(DerivedColumn expr) {
+    	Expression expression = expr.getExpression();
+        expr.setExpression(replaceExpression(expr.getExpression()));
+        if (createAliases() && expr.getExpression() != expression) {
+        	expr.setAlias(true);
         }
     }
     
-    /** 
-     * @see com.metamatrix.query.sql.LanguageVisitor#visit(com.metamatrix.query.sql.symbol.AliasSymbol)
-     */
-    public void visit(AliasSymbol obj) {
-        Expression replacement = replaceExpression(obj.getSymbol());
-        
-        if (replacement instanceof SingleElementSymbol) {
-            obj.setSymbol((SingleElementSymbol)replacement);
-        } else {
-            obj.setSymbol(new ExpressionSymbol(obj.getName(), replacement));
-        }
-    }
-    
-    public void visit(ExpressionSymbol expr) {
-        expr.setExpression(replaceExpression(expr.getExpression()));
-    }
-    
     /**
      * @see com.metamatrix.query.sql.LanguageVisitor#visit(BetweenCriteria)
      */
@@ -250,26 +204,22 @@
         }
     }
     
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
     	if (obj.getExpression() != null) { //account for count(*) - TODO: clean this up
     		obj.setExpression(replaceExpression(obj.getExpression()));
     	}
     }
     
-    /**
-     * Swap each ElementSymbol in GroupBy (other symbols are ignored).
-     * @param obj Object to remap
-     */
-    public void visit(GroupBy obj) {        
-        replaceSymbols(obj.getSymbols(), false);
+    public void visit(GroupBy obj) {
+    	List<Expression> expr = obj.getSymbols();
+        for (int i = 0; i < expr.size(); i++) {
+        	expr.set(i, replaceExpression(expr.get(i)));
+        }
     }
     
-    /**
-     * Swap each SingleElementSymbol in OrderBy (other symbols are ignored).
-     * @param obj Object to remap
-     */
-    public void visit(OrderBy obj) {
-        replaceSymbols(obj.getVariables(), true);        
+    @Override
+    public void visit(OrderByItem obj) {
+    	obj.setSortKey(replaceExpression(obj.getSortKey()));
     }
     
     public void visit(Limit obj) {

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionSymbolCollector.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionSymbolCollector.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionSymbolCollector.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -28,8 +28,8 @@
 import com.metamatrix.query.sql.LanguageObject;
 import com.metamatrix.query.sql.LanguageVisitor;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.util.ErrorMessageKeys;
 
 /**
@@ -72,7 +72,7 @@
      * called directly.
      * @param obj Language object
      */
-    public void visit(ExpressionSymbol obj) {
+    public void visit(DerivedColumn obj) {
         this.symbols.add(obj);
     }
 
@@ -81,7 +81,7 @@
      * called directly.
      * @param obj Language object
      */
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         this.symbols.add(obj);
     }
     

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -59,6 +59,7 @@
 import com.metamatrix.query.sql.lang.NotCriteria;
 import com.metamatrix.query.sql.lang.Option;
 import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
 import com.metamatrix.query.sql.lang.PredicateCriteria;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.QueryCommand;
@@ -75,6 +76,7 @@
 import com.metamatrix.query.sql.lang.UnaryFromClause;
 import com.metamatrix.query.sql.lang.Update;
 import com.metamatrix.query.sql.lang.XQuery;
+import com.metamatrix.query.sql.lang.OrderByItem.OrderSpecification;
 import com.metamatrix.query.sql.proc.AssignmentStatement;
 import com.metamatrix.query.sql.proc.Block;
 import com.metamatrix.query.sql.proc.BreakStatement;
@@ -90,22 +92,21 @@
 import com.metamatrix.query.sql.proc.Statement;
 import com.metamatrix.query.sql.proc.TranslateCriteria;
 import com.metamatrix.query.sql.proc.WhileStatement;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
 import com.metamatrix.query.sql.symbol.SearchedCaseExpression;
 import com.metamatrix.query.sql.symbol.SelectSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.symbol.Symbol;
 import com.metamatrix.query.util.ErrorMessageKeys;
 
 /**
@@ -730,30 +731,26 @@
         parts.add(SPACE);
         parts.add(ReservedWords.BY);
 		parts.add(SPACE);
-
-        List variables = obj.getVariables();
-        List types = obj.getTypes();
-        Iterator iter = variables.iterator();
-        Iterator typeIter = types.iterator();
-        while ( iter.hasNext() ) {
-		    SingleElementSymbol ses = (SingleElementSymbol)iter.next();
-            if (ses instanceof ElementSymbol && ((ElementSymbol)ses).getDisplayMode().equals(ElementSymbol.DisplayMode.SHORT_OUTPUT_NAME)) {
-                parts.add(registerNode(ses));
-            } else {
-                outputDisplayName(ses.getOutputName());
-            }
-            Boolean type = (Boolean) typeIter.next();
-            if( type.booleanValue() == OrderBy.DESC ) {
-                parts.add(SPACE);
-                parts.add(ReservedWords.DESC);
-            } // Don't print default "ASC"
-
-            if (iter.hasNext()) {
-                parts.add( ", " ); //$NON-NLS-1$
-            }
-	    }
+		List<OrderByItem> items = obj.getSortOrder();
+		for (Iterator<OrderByItem> iterator = items.iterator(); iterator.hasNext();) {
+			OrderByItem orderByItem = iterator.next();
+			parts.add(registerNode(orderByItem));
+			if (iterator.hasNext()) {
+				parts.add(", "); //$NON-NLS-1$
+			}
+		}
     }
     
+    @Override
+    public void visit(OrderByItem obj) {
+    	Expression ses = obj.getSortKey();
+        parts.add(registerNode(ses));
+        if(obj.getOrderingSpecification() == OrderSpecification.DESC) {
+            parts.add(SPACE);
+        	parts.add(ReservedWords.DESC);
+        }
+    }
+    
     public void visit(DynamicCommand obj) {
         parts.add(ReservedWords.EXECUTE);
         parts.add(SPACE);
@@ -1118,7 +1115,7 @@
 
     // ############ Visitor methods for symbol objects ####################
 
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         parts.add(obj.getAggregateFunction());
 		parts.add("("); //$NON-NLS-1$
 
@@ -1135,12 +1132,14 @@
 		parts.add(")"); //$NON-NLS-1$
     }
 
-    public void visit(AliasSymbol obj) {
-        parts.add(registerNode(obj.getSymbol()));
-        parts.add(SPACE);
-        parts.add(ReservedWords.AS);
-        parts.add(SPACE);
-        parts.add(escapeSinglePart(obj.getOutputName()));
+    public void visit(DerivedColumn obj) {
+        parts.add(registerNode(obj.getExpression()));
+        if (obj.isAlias()) {
+	        parts.add(SPACE);
+	        parts.add(ReservedWords.AS);
+	        parts.add(SPACE);
+	        parts.add(escapeSinglePart(obj.getOutputName()));
+        }
     }
 
     public void visit(AllInGroupSymbol obj) {
@@ -1231,7 +1230,7 @@
         if (obj.getDisplayMode().equals(ElementSymbol.DisplayMode.FULLY_QUALIFIED)) {
             name = obj.getName();
         } else if (obj.getDisplayMode().equals(ElementSymbol.DisplayMode.SHORT_OUTPUT_NAME)) {
-            String shortName = SingleElementSymbol.getShortName(name);
+            String shortName = Symbol.getShortName(name);
             //TODO: this is a hack - since we default to not supporting double quoted identifiers, we need to fully qualify reserved
             if (!isReservedWord(shortName)) {
                 name = shortName;
@@ -1251,10 +1250,6 @@
         }
     }
 
-    public void visit(ExpressionSymbol obj) {
-        parts.add(registerNode(obj.getExpression()));
-    }
-
     public void visit(Function obj) {
         String name = obj.getName();
         Expression[] args = obj.getArgs();

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/AggregateValidationVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/AggregateValidationVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/AggregateValidationVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -29,11 +29,11 @@
 import com.metamatrix.query.sql.LanguageObject;
 import com.metamatrix.query.sql.ReservedWords;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.SearchedCaseExpression;
 import com.metamatrix.query.sql.visitor.AggregateSymbolCollectorVisitor;
@@ -58,12 +58,12 @@
         this.groupExpressions = groupExpressions;
     }
     
-    public void visit(AggregateSymbol obj) {
+    public void visit(Aggregate obj) {
         Expression aggExp = obj.getExpression();
 
         // Check for any nested aggregates (which are not allowed)
         if(aggExp != null) {
-            Collection<AggregateSymbol> nestedAggs = AggregateSymbolCollectorVisitor.getAggregates(aggExp, true);
+            Collection<Aggregate> nestedAggs = AggregateSymbolCollectorVisitor.getAggregates(aggExp, true);
             if(nestedAggs.size() > 0) {
                 handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0039, nestedAggs), nestedAggs);
             }
@@ -83,7 +83,7 @@
         validateExpression(obj);
     }
     
-    public void visit(ExpressionSymbol obj) {
+    public void visit(DerivedColumn obj) {
         validateExpression(obj);
     }
     

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/UpdateValidationVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/UpdateValidationVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/UpdateValidationVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -144,12 +144,12 @@
                 symbol = ((AliasSymbol)symbol).getSymbol();
             }
 
-            if(symbol instanceof AggregateSymbol) {
-                handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0007, symbol));
-            } else if(symbol instanceof ExpressionSymbol) {
-                Expression expr = ((ExpressionSymbol)symbol).getExpression();
-                if(expr == null || expr instanceof Function) {
+            if(symbol instanceof DerivedColumn) {
+                Expression expr = ((DerivedColumn)symbol).getExpression();
+                if(expr instanceof Function) {
                     handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0008, symbol));
+                } else if (expr instanceof Aggregate) {
+                	handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0007, symbol));	
                 }
             }
     	}

Modified: branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -86,11 +86,11 @@
 import com.metamatrix.query.sql.proc.TranslateCriteria;
 import com.metamatrix.query.sql.proc.WhileStatement;
 import com.metamatrix.query.sql.symbol.AbstractCaseExpression;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
@@ -163,8 +163,8 @@
 		Iterator symbolIter = groupBySymbols.iterator();
 		while(symbolIter.hasNext()) {
             SingleElementSymbol symbol = (SingleElementSymbol)symbolIter.next();
-            if(symbol instanceof ExpressionSymbol) {
-                ExpressionSymbol exprSymbol = (ExpressionSymbol) symbol;
+            if(symbol instanceof DerivedColumn) {
+                DerivedColumn exprSymbol = (DerivedColumn) symbol;
                 Expression expr = exprSymbol.getExpression();
                 if(! (expr instanceof Function || expr instanceof AbstractCaseExpression)) {
                     handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.Expr_in_GROUP_BY_must_be_elem_func_case", expr), expr); //$NON-NLS-1$                        
@@ -569,7 +569,7 @@
 	    		ElementSymbol criteriaElement = (ElementSymbol) critEmlntIter.next();
 	    		if(transleElmnts.contains(criteriaElement)) {
 		    		Expression mappedExpr = (Expression) symbolMap.get(criteriaElement);
-		    		if(mappedExpr instanceof AggregateSymbol) {
+		    		if(mappedExpr instanceof Aggregate) {
 						handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0022, criteriaElement), criteriaElement);
 		    		}
 

Modified: branches/symbol_refactoring_61/engine/src/main/javacc/com/metamatrix/query/parser/SQLParser.jj
===================================================================
--- branches/symbol_refactoring_61/engine/src/main/javacc/com/metamatrix/query/parser/SQLParser.jj	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/main/javacc/com/metamatrix/query/parser/SQLParser.jj	2009-03-03 17:26:43 UTC (rev 532)
@@ -1478,52 +1478,29 @@
 		]
 	)
 	{
-		// Validate alias
-        String alias = null;
-        if(aliasToken != null) { 
-            alias = validateAlias(aliasToken.image);
-        }    
-	
 		if(allInGroupToken != null) {
-			if(aliasToken == null) {
-				// Group.*
-				return new AllInGroupSymbol(validateMetadataID(allInGroupToken.image));
+			// Group.*
+			return new AllInGroupSymbol(validateMetadataID(allInGroupToken.image));
+		} else {
+			String name = null; 
+			if (aliasToken == null) {
+			    if(expression instanceof ElementSymbol) {
+			    	name = ((ElementSymbol)expression).getShortName();
+			    } else {
+			    	name = generateFunctionName(info, null);
+			    }
 			} else {
-				Object[] params = new Object[] { allInGroupToken.image };				
-				throw new ParseException(QueryPlugin.Util.getString("SQLParser.Cant_alias_star", params)); //$NON-NLS-1$
+				name = validateAlias(aliasToken.image);
 			}
-		} else if(expression instanceof ElementSymbol) {
-			SingleElementSymbol es = (ElementSymbol) expression;
-			if(aliasToken != null) {
-				// Aliased element
-				es = new AliasSymbol(alias, es);
-			}
-			return es;
-		} else if(expression instanceof AggregateSymbol) {
-			// This can happen if the aggregate symbol is surrounded by ( ), which
-			// can happen when queries are generated in ODBC
-			AggregateSymbol aggSymbol = (AggregateSymbol) expression;
-			if(aliasToken != null) {
-				return new AliasSymbol(alias, aggSymbol);
-			} else {
-				return aggSymbol;
-			}			
-		} else {
-			String functionName = generateFunctionName(info, null);
-			SingleElementSymbol expSymbol = new ExpressionSymbol(functionName, expression);
-			if(aliasToken != null) { 
-				expSymbol = new AliasSymbol(alias, expSymbol);
-			}
-			return expSymbol;
-		}
+			return new DerivedColumn(name, expression, aliasToken != null);
+		} 
 	}
 }
 
-AggregateSymbol aggregateSymbol(ParseInfo info) :
+Aggregate aggregate(ParseInfo info) :
 {
 	Token functionToken = null;
 	Token starToken = null;
-	AggregateSymbol agg = null;
 	boolean isDistinct = false;
 	Expression expression = null;
 }
@@ -1556,16 +1533,7 @@
 		}
 		
 		String func = functionToken.image.toUpperCase();
-		String name = generateFunctionName(info, func);
-		if(starToken == null) { 
-			// Aggregate
-			agg = new AggregateSymbol(name, func, isDistinct, expression);
-		} else {
-			// COUNT(*)			
-			agg = new AggregateSymbol(name, func, false, null);
-		}
-		
-		return agg;
+		return new Aggregate(func, isDistinct, expression);
 	}
 }
 
@@ -2207,18 +2175,19 @@
 GroupBy groupBy(ParseInfo info) :
 {
 	GroupBy groupBy = new GroupBy();
-	SingleElementSymbol symbol = null;
+	Expression expr = null;
 }
 {
 	<GROUP> <BY>
-	(	symbol = groupByItem(info)
+	(expr = expression(info)
+
 		{
-			groupBy.addSymbol(symbol);
+			groupBy.addSymbol(expr);
 		}
 		
-		(<COMMA> symbol = groupByItem(info)
+		(<COMMA> expr = expression(info)
 			{
-				groupBy.addSymbol(symbol);
+				groupBy.addSymbol(expr);
 			}
 		)*
 	)
@@ -2228,31 +2197,6 @@
 }
 
 /**
- * <p>Parse a GROUP BY list item.  </p>
- * @return Parsed group by item
- * @throws ParseException if parsing failed
- */
-SingleElementSymbol groupByItem(ParseInfo info) :
-{
-	Expression expr = null;
-	SingleElementSymbol symbol = null;
-}
-{
-	expr = expression(info)
-	{
-		if(expr instanceof ElementSymbol) {
-			symbol = (ElementSymbol) expr;
-		} else {
-			String exprName = generateFunctionName(info, null);
-			symbol = new ExpressionSymbol(exprName, expr);
-		}
-	}
-	{
-		return symbol;
-	}
-}
-
-/**
  * <p>Parse a HAVING clause.  </p>
  * @return Parsed having
  * @throws ParseException if parsing failed
@@ -2590,7 +2534,7 @@
 		)
 		|
 		// Aggregate function
-		(expression=aggregateSymbol(info))
+		(expression=aggregate(info))
 		|
 		// Function
 		LOOKAHEAD(2) (expression=function(info))

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/dqp/internal/datamgr/language/TestAggregateImpl.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/dqp/internal/datamgr/language/TestAggregateImpl.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/dqp/internal/datamgr/language/TestAggregateImpl.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -26,7 +26,7 @@
 
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.sql.ReservedWords;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 
 import junit.framework.TestCase;
@@ -42,10 +42,9 @@
     }
 
     public static AggregateImpl example(String name, String functionName, boolean distinct, int value) throws Exception {
-        AggregateSymbol symbol = new AggregateSymbol(name,
-                                                     functionName,
+        Aggregate symbol = new Aggregate(functionName,
                                                      distinct,
-                                                      new Constant(new Integer(value)));
+                                                     new Constant(new Integer(value)));
         return (AggregateImpl)TstLanguageBridgeFactory.factory.translate(symbol);
         
     }

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/TestJoinWithFunction.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/TestJoinWithFunction.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/TestJoinWithFunction.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -35,7 +35,7 @@
 import com.metamatrix.query.processor.relational.RelationalPlan;
 import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.Constant;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 
 /**
  * <p><code>TestCase</code> to cover planning and optimization of JOINs which 
@@ -289,7 +289,7 @@
 		Constant expectedConst = new Constant(new Double(10.0));
 		assertEquals("Did not get expected constant value for SqrtTop in root node of plan: ",  //$NON-NLS-1$
 				expectedConst, 
-				((ExpressionSymbol) ((AliasSymbol) elem.get(8)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
+				((DerivedColumn) ((AliasSymbol) elem.get(8)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
 			);
 	}
 
@@ -359,7 +359,7 @@
 		Constant expectedConst = new Constant(new Double(10.0));
 		assertEquals("Did not get expected constant value for SqrtLeft in root node of plan: ",  //$NON-NLS-1$
 				expectedConst, 
-				((ExpressionSymbol) ((AliasSymbol) elem.get(8)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
+				((DerivedColumn) ((AliasSymbol) elem.get(8)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
 			); 
 	}
 
@@ -427,11 +427,11 @@
 		Constant expectedConst = new Constant(new Double(10.0));
 		assertEquals("Did not get expected constant value for SqrtLeft in root node of plan: ",  //$NON-NLS-1$
 				expectedConst, 
-				((ExpressionSymbol) ((AliasSymbol) elem.get(8)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
+				((DerivedColumn) ((AliasSymbol) elem.get(8)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
 			); 
 		assertEquals("Did not get expected constant value for SqrtTop in root node of plan: ",  //$NON-NLS-1$
 				expectedConst, 
-				((ExpressionSymbol) ((AliasSymbol) elem.get(9)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
+				((DerivedColumn) ((AliasSymbol) elem.get(9)).getSymbol()).getExpression()  // should be a AliasSymbol containing an expression 
 			);
 	}
 }

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCapabilitiesUtil.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCapabilitiesUtil.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCapabilitiesUtil.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -41,11 +41,11 @@
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.sql.lang.JoinType;
 import com.metamatrix.query.sql.lang.SetQuery.Operation;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.ScalarSubquery;
 import com.metamatrix.query.unittest.FakeMetadataFacade;
@@ -186,13 +186,13 @@
      */
     public void testSupportsFunctionInGroupBy() throws Exception {
         Function f = new Function("concat", new Expression[] { new Constant("a"), new Constant("b") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        ExpressionSymbol expr = new ExpressionSymbol("e", f); //$NON-NLS-1$
+        DerivedColumn expr = new DerivedColumn("e", f); //$NON-NLS-1$
         List cols = new ArrayList();
         cols.add(expr);
         helpTestSupportsAggregates(false, false, cols);
     }
 
-    public void helpTestSupportsAggregateFunction(SourceCapabilities caps, AggregateSymbol aggregate, boolean expectedValue) throws QueryMetadataException, MetaMatrixComponentException {
+    public void helpTestSupportsAggregateFunction(SourceCapabilities caps, Aggregate aggregate, boolean expectedValue) throws QueryMetadataException, MetaMatrixComponentException {
         // Set up metadata
         FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
         FakeMetadataObject modelID = metadata.getStore().findObject("pm1", FakeMetadataObject.MODEL); //$NON-NLS-1$
@@ -211,7 +211,7 @@
         BasicSourceCapabilities caps = new BasicSourceCapabilities();
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+        Aggregate aggregate = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -223,7 +223,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, false);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+        Aggregate aggregate = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -235,7 +235,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, false);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+        Aggregate aggregate = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
@@ -247,7 +247,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, false);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.COUNT, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.COUNT, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -259,7 +259,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+        Aggregate aggregate = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -271,7 +271,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.COUNT, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.COUNT, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
@@ -282,7 +282,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_SUM, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.SUM, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.SUM, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -293,7 +293,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_SUM, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.SUM, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.SUM, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
@@ -304,7 +304,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_AVG, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.AVG, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.AVG, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -315,7 +315,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_AVG, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.AVG, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.AVG, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
@@ -326,7 +326,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MIN, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.MIN, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.MIN, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -337,7 +337,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MIN, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.MIN, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.MIN, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
@@ -348,7 +348,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.MAX, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.MAX, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -359,7 +359,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.MAX, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.MAX, false, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
@@ -371,7 +371,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_DISTINCT, false);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.MAX, true, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.MAX, true, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, false); 
     }    
@@ -383,7 +383,7 @@
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, true);
         caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_DISTINCT, true);
         
-        AggregateSymbol aggregate = new AggregateSymbol("expr", ReservedWords.MAX, true, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
+        Aggregate aggregate = new Aggregate(ReservedWords.MAX, true, new ElementSymbol("x")); //$NON-NLS-1$ //$NON-NLS-2$
         
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/parser/TestParser.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/parser/TestParser.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/parser/TestParser.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -57,6 +57,7 @@
 import com.metamatrix.query.sql.lang.MatchCriteria;
 import com.metamatrix.query.sql.lang.NotCriteria;
 import com.metamatrix.query.sql.lang.OrderBy;
+import com.metamatrix.query.sql.lang.OrderByItem;
 import com.metamatrix.query.sql.lang.PredicateCriteria;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.SPParameter;
@@ -70,6 +71,7 @@
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
 import com.metamatrix.query.sql.lang.UnaryFromClause;
 import com.metamatrix.query.sql.lang.Update;
+import com.metamatrix.query.sql.lang.OrderByItem.OrderSpecification;
 import com.metamatrix.query.sql.lang.SetQuery.Operation;
 import com.metamatrix.query.sql.proc.AssignmentStatement;
 import com.metamatrix.query.sql.proc.Block;
@@ -86,15 +88,14 @@
 import com.metamatrix.query.sql.proc.Statement;
 import com.metamatrix.query.sql.proc.TranslateCriteria;
 import com.metamatrix.query.sql.proc.WhileStatement;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
@@ -459,7 +460,7 @@
 		From from = new From();
 		from.addClause(jp);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("myG.a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("myG.a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("myH.b")); //$NON-NLS-1$
@@ -486,7 +487,7 @@
 		From from = new From();
 		from.addClause(jp);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("myG.a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("myG.a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("myH.b")); //$NON-NLS-1$
@@ -513,7 +514,7 @@
 		From from = new From();
 		from.addClause(jp);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("myG.a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("myG.a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("myH.b")); //$NON-NLS-1$
@@ -540,7 +541,7 @@
 		From from = new From();
 		from.addClause(jp);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("myG.a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("myG.a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("myH.b")); //$NON-NLS-1$
@@ -567,7 +568,7 @@
 		From from = new From();
 		from.addClause(jp);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("myG.a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("myG.a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("myH.b")); //$NON-NLS-1$
@@ -615,7 +616,7 @@
 		from.addGroup(g);
 
 		Function f = new Function("CONVERT", new Expression[] {new ElementSymbol("a", false), new Constant("string")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-		ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
+		DerivedColumn es = new DerivedColumn("expr", f); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 
@@ -635,7 +636,7 @@
 
 		Function f = new Function("CONVERT", new Expression[] {new ElementSymbol("a", false), new Constant("timestamp")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		Function f2 = new Function("CONVERT", new Expression[] {f, new Constant("string")}); //$NON-NLS-1$ //$NON-NLS-2$
-		ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+		DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 
@@ -658,7 +659,7 @@
 		Function f = new Function("concat", new Expression[] {new ElementSymbol("a", false), new Constant("x")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		Function f2 = new Function("length", new Expression[] {f}); //$NON-NLS-1$
 		Function f3 = new Function("+", new Expression[] {new Constant(new Integer(5)), f2}); //$NON-NLS-1$
-		ExpressionSymbol es = new ExpressionSymbol("expr", f3); //$NON-NLS-1$
+		DerivedColumn es = new DerivedColumn("expr", f3); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 
@@ -677,10 +678,9 @@
 		from.addGroup(g);
 
 		Function f = new Function("replace", new Expression[] {new ElementSymbol("a", false), new Constant("x"), new Constant("y")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-		ExpressionSymbol es = new ExpressionSymbol("y", f); //$NON-NLS-1$
-		AliasSymbol as = new AliasSymbol("y", es); //$NON-NLS-1$
+		DerivedColumn es = new DerivedColumn("y", f, true); //$NON-NLS-1$
 		Select select = new Select();
-		select.addSymbol(as);
+		select.addSymbol(es);
 
 		Query query = new Query();
 		query.setSelect(select);
@@ -697,7 +697,7 @@
 		from.addGroup(g);
 
 		Function f = new Function("cast", new Expression[] {new ElementSymbol("a", false), new Constant("string")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 
-		ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
+		DerivedColumn es = new DerivedColumn("expr", f); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 
@@ -717,7 +717,7 @@
 
 		Function f = new Function("cast", new Expression[] {new ElementSymbol("a", false), new Constant("timestamp")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 
 		Function f2 = new Function("cast", new Expression[] {f, new Constant("string")}); //$NON-NLS-1$ //$NON-NLS-2$
-		ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+		DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 
@@ -736,10 +736,9 @@
         from.addGroup(g);
 
         Function f = new Function("left", new Expression[] {new ElementSymbol("fullname", false), new Constant(new Integer(3))}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -756,10 +755,9 @@
         from.addGroup(g);
 
         Function f = new Function("right", new Expression[] {new ElementSymbol("fullname", false), new Constant(new Integer(3))}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -776,10 +774,9 @@
         from.addGroup(g);
 
         Function f = new Function("char", new Expression[] { new Constant("x")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -796,10 +793,9 @@
         from.addGroup(g);
 
         Function f = new Function("insert", new Expression[] { new Constant("x"), new Constant(new Integer(1)), new Constant("a")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -822,7 +818,7 @@
         
         Select select = new Select();
 //        select.addSymbol( new ExpressionSymbol( new Constant( new Integer(1) ) ) );
-        select.addSymbol(  new ExpressionSymbol( "exp", new Constant( new Integer(1) ) ) );    //$NON-NLS-1$
+        select.addSymbol(  new DerivedColumn( "exp", new Constant( new Integer(1) ) ) );    //$NON-NLS-1$
 
         Query query = new Query();
         query.setSelect(select);
@@ -841,7 +837,7 @@
         from.addGroup(g);
 
         Function f = new Function("translate", new Expression[] { new Constant("x"), new Constant("x"), new Constant("y")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -861,10 +857,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_FRAC_SECOND"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -882,10 +877,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_SECOND"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -903,10 +897,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_MINUTE"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -924,10 +917,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_HOUR"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -945,10 +937,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_DAY"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -966,10 +957,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_WEEK"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -987,10 +977,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_QUARTER"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -1008,10 +997,9 @@
 
         Function f = new Function("timestampadd", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_YEAR"), new Constant(new Integer(10)), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -1029,10 +1017,9 @@
 
         Function f = new Function("timestampdiff", new Expression[] { //$NON-NLS-1$
             new Constant("SQL_TSI_FRAC_SECOND"), new Constant("2003-05-01 10:20:10"), new Constant("2003-05-01 10:20:30")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol as = new AliasSymbol("x", es); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("x", f, true); //$NON-NLS-1$
         Select select = new Select();
-        select.addSymbol(as);
+        select.addSymbol(es);
 
         Query query = new Query();
         query.setSelect(select);
@@ -1050,7 +1037,7 @@
 
         Function f = new Function("+", new Expression[] {new Constant(new Integer(5)), new Constant(new Integer(2))}); //$NON-NLS-1$
         Function f2 = new Function("+", new Expression[] {f, new Constant(new Integer(3))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1070,7 +1057,7 @@
 
         Function f = new Function("+", new Expression[] {new Constant(new Integer(5)), new Constant(new Integer(2))}); //$NON-NLS-1$
         Function f2 = new Function("-", new Expression[] {f, new Constant(new Integer(3))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1091,7 +1078,7 @@
         Function f = new Function("*", new Expression[] {new Constant(new Integer(2)), new Constant(new Integer(3))}); //$NON-NLS-1$
         Function f2 = new Function("+", new Expression[] {new Constant(new Integer(5)), f}); //$NON-NLS-1$
         
-        ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1111,7 +1098,7 @@
 
         Function f = new Function("*", new Expression[] {new Constant(new Integer(5)), new Constant(new Integer(2))}); //$NON-NLS-1$
         Function f2 = new Function("+", new Expression[] {f, new Constant(new Integer(3))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1131,7 +1118,7 @@
 
         Function f = new Function("*", new Expression[] {new Constant(new Integer(5)), new Constant(new Integer(2))}); //$NON-NLS-1$
         Function f2 = new Function("*", new Expression[] {f, new Constant(new Integer(3))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1153,7 +1140,7 @@
         Function f2 = new Function("*", new Expression[] {new Constant(new Integer(4)), new Constant(new Integer(5))}); //$NON-NLS-1$
         Function f3 = new Function("+", new Expression[] {new Constant(new Integer(1)), f}); //$NON-NLS-1$
         Function f4 = new Function("+", new Expression[] {f3, f2}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f4); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f4); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1175,7 +1162,7 @@
         Function f2 = new Function("*", new Expression[] {new Constant(new Integer(3)), new Constant(new Integer(4))}); //$NON-NLS-1$
         Function f3 = new Function("+", new Expression[] {f, f2}); //$NON-NLS-1$
         Function f4 = new Function("+", new Expression[] {f3, new Constant(new Integer(5))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f4); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f4); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1196,7 +1183,7 @@
         Function f = new Function("-", new Expression[] {new Constant(new Integer(5)), new Constant(new Integer(4))}); //$NON-NLS-1$
         Function f2 = new Function("-", new Expression[] {f, new Constant(new Integer(3))}); //$NON-NLS-1$
         Function f3 = new Function("-", new Expression[] {f2, new Constant(new Integer(2))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f3); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f3); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1217,7 +1204,7 @@
         Function f = new Function("/", new Expression[] {new Constant(new Integer(5)), new Constant(new Integer(4))}); //$NON-NLS-1$
         Function f2 = new Function("/", new Expression[] {f, new Constant(new Integer(3))}); //$NON-NLS-1$
         Function f3 = new Function("/", new Expression[] {f2, new Constant(new Integer(2))}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f3); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f3); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1237,7 +1224,7 @@
 
         Function f = new Function("||", new Expression[] {new Constant("a"), new Constant("b")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         Function f2 = new Function("||", new Expression[] {f, new Constant("c")}); //$NON-NLS-1$ //$NON-NLS-2$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f2); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f2); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1259,7 +1246,7 @@
         Function f2 = new Function("+", new Expression[] {new Constant(new Integer(5)), f}); //$NON-NLS-1$
         Function f3 = new Function("+", new Expression[] {new Constant(new Integer(2)), new Constant(new Integer(3))}); //$NON-NLS-1$
         Function f4 = new Function("||", new Expression[] {f3, f2}); //$NON-NLS-1$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f4); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f4); //$NON-NLS-1$
         Select select = new Select();
         select.addSymbol(es);
 
@@ -1328,8 +1315,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new AliasSymbol("c",  //$NON-NLS-1$
-			new AggregateSymbol("c", "COUNT", false, new ElementSymbol("a", false)))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		select.addSymbol(new DerivedColumn("c", new Aggregate("COUNT", false, new ElementSymbol("a", false)), true)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		
 				
 		Query query = new Query();
@@ -1347,8 +1333,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new AliasSymbol("c",  //$NON-NLS-1$
-            new AggregateSymbol("c", "COUNT", false, new ElementSymbol("a", false)))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        select.addSymbol(new DerivedColumn("c", new Aggregate("COUNT", false, new ElementSymbol("a", false)))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         
                 
         Query query = new Query();
@@ -1372,7 +1357,7 @@
 		groupBy.addSymbol(new ElementSymbol("a")); //$NON-NLS-1$
 		
 		Criteria having = new CompareCriteria(
-			new AggregateSymbol("count", "COUNT", false, new ElementSymbol("b", false)), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			new Aggregate("COUNT", false, new ElementSymbol("b", false)), //$NON-NLS-1$ //$NON-NLS-2$ 
 			CompareCriteria.GT,
 			new Constant(new Integer(0)) );
 				
@@ -1403,7 +1388,7 @@
 		CompoundCriteria having = new CompoundCriteria();
 		having.setOperator(CompoundCriteria.AND);
 		having.addCriteria(new CompareCriteria(
-			new AggregateSymbol("count", "COUNT", false, new ElementSymbol("b", false)), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			new Aggregate("COUNT", false, new ElementSymbol("b", false)), //$NON-NLS-1$ //$NON-NLS-2$ 
 			CompareCriteria.GT,
 			new Constant(new Integer(0)) ));
 		having.addCriteria(new CompareCriteria(
@@ -1459,12 +1444,11 @@
         from.addGroup(g);
 
         Select select = new Select();
-        AggregateSymbol agg1 = new AggregateSymbol("count", "COUNT", false, new ElementSymbol("a", false)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        AggregateSymbol agg2 = new AggregateSymbol("sum", "SUM", false, new ElementSymbol("a", false)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        Aggregate agg1 = new Aggregate("COUNT", false, new ElementSymbol("a", false)); //$NON-NLS-1$ //$NON-NLS-2$ 
+        Aggregate agg2 = new Aggregate("SUM", false, new ElementSymbol("a", false)); //$NON-NLS-1$ //$NON-NLS-2$ 
         Function f = new Function("*", new Expression[] { agg1, agg2 }); //$NON-NLS-1$
-        ExpressionSymbol expr = new ExpressionSymbol("expr", f); //$NON-NLS-1$
-        AliasSymbol alias = new AliasSymbol("c", expr); //$NON-NLS-1$
-        select.addSymbol(alias);        
+        DerivedColumn expr = new DerivedColumn("c", f, true); //$NON-NLS-1$
+        select.addSymbol(expr);        
                 
         Query query = new Query();
         query.setSelect(select);
@@ -1482,7 +1466,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol(
+		select.addSymbol(new DerivedColumn(
 			"expr",  //$NON-NLS-1$
 			new Function("-", new Expression[] { new Constant(new Integer(5)), new Constant(null) }) ) ); //$NON-NLS-1$
 		select.addSymbol(new ElementSymbol("a.g1.c1")); //$NON-NLS-1$
@@ -1503,7 +1487,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant("abc"))); //$NON-NLS-1$ //$NON-NLS-2$
+		select.addSymbol(new DerivedColumn("expr", new Constant("abc"))); //$NON-NLS-1$ //$NON-NLS-2$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1522,7 +1506,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant("O'Leary"))); //$NON-NLS-1$ //$NON-NLS-2$
+		select.addSymbol(new DerivedColumn("expr", new Constant("O'Leary"))); //$NON-NLS-1$ //$NON-NLS-2$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1540,7 +1524,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant("'abc'"))); //$NON-NLS-1$ //$NON-NLS-2$
+		select.addSymbol(new DerivedColumn("expr", new Constant("'abc'"))); //$NON-NLS-1$ //$NON-NLS-2$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1558,7 +1542,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant("a'b'c"))); //$NON-NLS-1$ //$NON-NLS-2$
+		select.addSymbol(new DerivedColumn("expr", new Constant("a'b'c"))); //$NON-NLS-1$ //$NON-NLS-2$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1576,7 +1560,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant(" \" "))); //$NON-NLS-1$ //$NON-NLS-2$
+		select.addSymbol(new DerivedColumn("expr", new Constant(" \" "))); //$NON-NLS-1$ //$NON-NLS-2$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1594,7 +1578,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant(new Long(123456789012L)))); //$NON-NLS-1$
+		select.addSymbol(new DerivedColumn("expr", new Constant(new Long(123456789012L)))); //$NON-NLS-1$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1612,7 +1596,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant(new BigInteger("1000000000000000000000000")))); //$NON-NLS-1$ //$NON-NLS-2$
+		select.addSymbol(new DerivedColumn("expr", new Constant(new BigInteger("1000000000000000000000000")))); //$NON-NLS-1$ //$NON-NLS-2$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1630,7 +1614,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant(new Double(1.3e8)))); //$NON-NLS-1$
+		select.addSymbol(new DerivedColumn("expr", new Constant(new Double(1.3e8)))); //$NON-NLS-1$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1648,7 +1632,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant(new Double(-1.3e-6)))); //$NON-NLS-1$
+		select.addSymbol(new DerivedColumn("expr", new Constant(new Double(-1.3e-6)))); //$NON-NLS-1$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1666,7 +1650,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", new Constant(new Double(-1.3e+8)))); //$NON-NLS-1$
+		select.addSymbol(new DerivedColumn("expr", new Constant(new Double(-1.3e+8)))); //$NON-NLS-1$
 						
 		Query query = new Query();
 		query.setSelect(select);
@@ -1684,7 +1668,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(java.sql.Date.valueOf("2002-10-02")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(java.sql.Date.valueOf("2002-10-02")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1702,7 +1686,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(java.sql.Date.valueOf("2002-09-01")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(java.sql.Date.valueOf("2002-09-01")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1725,7 +1709,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(java.sql.Time.valueOf("11:10:00")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(java.sql.Time.valueOf("11:10:00")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1743,7 +1727,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(java.sql.Time.valueOf("5:10:00")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(java.sql.Time.valueOf("5:10:00")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1766,7 +1750,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(java.sql.Timestamp.valueOf("2002-10-02 19:00:02.50")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(java.sql.Timestamp.valueOf("2002-10-02 19:00:02.50")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1784,7 +1768,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(Boolean.valueOf("true")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(Boolean.valueOf("true")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1801,7 +1785,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(Boolean.valueOf("true")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(Boolean.valueOf("true")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1819,7 +1803,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(Boolean.valueOf("false")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(Boolean.valueOf("false")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1837,7 +1821,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        select.addSymbol(new ExpressionSymbol("expr", new Constant(Boolean.valueOf("false")))); //$NON-NLS-1$ //$NON-NLS-2$
+        select.addSymbol(new DerivedColumn("expr", new Constant(Boolean.valueOf("false")))); //$NON-NLS-1$ //$NON-NLS-2$
                         
         Query query = new Query();
         query.setSelect(select);
@@ -1897,7 +1881,7 @@
 		From from = new From();
 		from.addGroup(g);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("b")); //$NON-NLS-1$
@@ -1918,7 +1902,7 @@
 		from.addGroup(g);
 		from.addGroup(h);
 
-		AliasSymbol as = new AliasSymbol("myA", new ElementSymbol("a")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn as = new DerivedColumn("myA", new ElementSymbol("a"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		select.addSymbol(new ElementSymbol("b")); //$NON-NLS-1$
@@ -2216,7 +2200,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		ExpressionSymbol a = new ExpressionSymbol("expr", new Constant("g\".\"a"));  //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn a = new DerivedColumn("expr", new Constant("g\".\"a"));  //$NON-NLS-1$ //$NON-NLS-2$
 		select.addSymbol(a);
 
 		Query query = new Query();
@@ -2235,7 +2219,7 @@
 		from.addGroup(g);
 
 		Select select = new Select();
-		AliasSymbol a = new AliasSymbol("select", new ElementSymbol("g.x"));  //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn a = new DerivedColumn("select", new ElementSymbol("g.x"), true);  //$NON-NLS-1$ //$NON-NLS-2$
 		select.addSymbol(a);
 
 		Query query = new Query();
@@ -2254,7 +2238,7 @@
         from.addGroup(g);
 
         Select select = new Select();
-        AliasSymbol a = new AliasSymbol("year", new ElementSymbol("g.x"));  //$NON-NLS-1$ //$NON-NLS-2$
+        DerivedColumn a = new DerivedColumn("year", new ElementSymbol("g.x"), true);  //$NON-NLS-1$ //$NON-NLS-2$
         select.addSymbol(a);
 
         Query query = new Query();
@@ -2652,11 +2636,8 @@
 
 		Criteria crit = new CompareCriteria(new ElementSymbol("b"), CompareCriteria.EQ, new ElementSymbol("aString")); //$NON-NLS-1$ //$NON-NLS-2$
 
-		ArrayList elements = new ArrayList();
-		elements.add(new ElementSymbol("c")); //$NON-NLS-1$
-		ArrayList orderTypes = new ArrayList();
-		orderTypes.add(Boolean.FALSE);
-		OrderBy orderBy = new OrderBy(elements, orderTypes);
+		OrderBy orderBy = new OrderBy();
+		orderBy.addItem(new OrderByItem(new ElementSymbol("c"), OrderSpecification.DESC)); //$NON-NLS-1$
 
 		Query query = new Query(select, from, crit, orderBy, null);
 		helpTest("SELECT a FROM db.g WHERE b = aString ORDER BY c desc",  //$NON-NLS-1$
@@ -2699,13 +2680,9 @@
 
 		Criteria crit = new CompareCriteria(new ElementSymbol("b"), CompareCriteria.EQ, new ElementSymbol("aString")); //$NON-NLS-1$ //$NON-NLS-2$
 
-		ArrayList elements = new ArrayList();
-		elements.add(new ElementSymbol("c")); //$NON-NLS-1$
-		elements.add(new ElementSymbol("d")); //$NON-NLS-1$
-		ArrayList orderTypes = new ArrayList();
-		orderTypes.add(Boolean.FALSE);
-		orderTypes.add(Boolean.FALSE);
-		OrderBy orderBy = new OrderBy(elements, orderTypes);
+		OrderBy orderBy = new OrderBy();
+		orderBy.addItem(new OrderByItem(new ElementSymbol("c"), OrderSpecification.DESC)); //$NON-NLS-1$
+		orderBy.addItem(new OrderByItem(new ElementSymbol("d"), OrderSpecification.DESC)); //$NON-NLS-1$
 
 		Query query = new Query(select, from, crit, orderBy, null);
 		helpTest("SELECT a FROM db.g WHERE b = aString ORDER BY c desc,d desc",  //$NON-NLS-1$
@@ -2725,13 +2702,9 @@
 
 		Criteria crit = new CompareCriteria(new ElementSymbol("b"), CompareCriteria.EQ, new ElementSymbol("aString")); //$NON-NLS-1$ //$NON-NLS-2$
 
-		ArrayList elements = new ArrayList();
-		elements.add(new ElementSymbol("c")); //$NON-NLS-1$
-		elements.add(new ElementSymbol("d")); //$NON-NLS-1$
-		ArrayList orderTypes = new ArrayList();
-		orderTypes.add(Boolean.FALSE);
-		orderTypes.add(Boolean.TRUE);
-		OrderBy orderBy = new OrderBy(elements, orderTypes);
+		OrderBy orderBy = new OrderBy();
+		orderBy.addItem(new OrderByItem(new ElementSymbol("c"), OrderSpecification.DESC)); //$NON-NLS-1$
+		orderBy.addItem(new OrderByItem(new ElementSymbol("d"), OrderSpecification.ASC)); //$NON-NLS-1$
 
 		Query query = new Query(select, from, crit, orderBy, null);
 		helpTest("SELECT a FROM db.g WHERE b = aString ORDER BY c desc,d",  //$NON-NLS-1$
@@ -2939,7 +2912,7 @@
     public void testNoFromClause(){
         Select select = new Select();
         ElementSymbol a = new ElementSymbol("a"); //$NON-NLS-1$
-        ExpressionSymbol b = new ExpressionSymbol("expr", new Constant(new Integer(5), Integer.class)); //$NON-NLS-1$
+        DerivedColumn b = new DerivedColumn("expr", new Constant(new Integer(5), Integer.class)); //$NON-NLS-1$
         select.addSymbol(a);
         select.addSymbol(b);
         Query query = new Query();
@@ -3048,7 +3021,7 @@
 
         Select select = new Select();
         Reference ref0 = new Reference(0);
-        ExpressionSymbol expr = new ExpressionSymbol("expr", ref0); //$NON-NLS-1$
+        DerivedColumn expr = new DerivedColumn("expr", ref0); //$NON-NLS-1$
         select.addSymbol(expr);
 
         Reference ref1 = new Reference(1);
@@ -5333,7 +5306,7 @@
 		Query query = new Query();
 		Select select = new Select();
 		Constant c = new Constant("\u05e0"); //$NON-NLS-1$
-		select.addSymbol(new ExpressionSymbol("expr", c)); //$NON-NLS-1$
+		select.addSymbol(new DerivedColumn("expr", c)); //$NON-NLS-1$
 		query.setSelect(select);
 
 		helpTest(sql, query.toString(), query);
@@ -5433,7 +5406,7 @@
         Query query = new Query();
         Select select = new Select();
         Function func1 = new Function("yowza_yowza", new Expression[] { }); //$NON-NLS-1$
-        ExpressionSymbol exprSymbol = new ExpressionSymbol("expr", func1); //$NON-NLS-1$
+        DerivedColumn exprSymbol = new DerivedColumn("expr", func1); //$NON-NLS-1$
         select.addSymbol(exprSymbol);        
         query.setSelect(select);
         
@@ -5733,7 +5706,7 @@
 
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
-        s2.addSymbol(new ExpressionSymbol("expr", new ScalarSubquery(q1))); //$NON-NLS-1$
+        s2.addSymbol(new DerivedColumn("expr", new ScalarSubquery(q1))); //$NON-NLS-1$
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
         Query q2 = new Query();
@@ -5756,7 +5729,7 @@
         q1.setFrom(f1);
 
         Select s2 = new Select();
-        s2.addSymbol(new ExpressionSymbol("expr", new ScalarSubquery(q1))); //$NON-NLS-1$
+        s2.addSymbol(new DerivedColumn("expr", new ScalarSubquery(q1))); //$NON-NLS-1$
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
         Query q2 = new Query();
@@ -5779,7 +5752,7 @@
         q1.setFrom(f1);
 
         Select s2 = new Select();
-        s2.addSymbol(new ExpressionSymbol("expr", new ScalarSubquery(q1))); //$NON-NLS-1$
+        s2.addSymbol(new DerivedColumn("expr", new ScalarSubquery(q1))); //$NON-NLS-1$
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
@@ -5804,7 +5777,7 @@
 
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
-        s2.addSymbol(new AliasSymbol("X", new ExpressionSymbol("expr", new ScalarSubquery(q1)))); //$NON-NLS-1$ //$NON-NLS-2$
+        s2.addSymbol(new DerivedColumn("X", new ScalarSubquery(q1), true)); //$NON-NLS-1$
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
         Query q2 = new Query();
@@ -5820,7 +5793,7 @@
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
        
-        s2.addSymbol(new AliasSymbol("X", new ExpressionSymbol("expr", QueryParser.getQueryParser().parseExpression("(SELECT e1 FROM m.g1) + 2")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s2.addSymbol(new DerivedColumn("X", QueryParser.getQueryParser().parseExpression("(SELECT e1 FROM m.g1) + 2"), true)); //$NON-NLS-1$ //$NON-NLS-2$
 
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
@@ -5837,7 +5810,7 @@
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
         
-        s2.addSymbol(new AliasSymbol("X", new ExpressionSymbol("expr", QueryParser.getQueryParser().parseExpression("3 + (SELECT e1 FROM m.g1)")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s2.addSymbol(new DerivedColumn("X", QueryParser.getQueryParser().parseExpression("3 + (SELECT e1 FROM m.g1)"), true)); //$NON-NLS-1$ //$NON-NLS-2$
 
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
@@ -5854,7 +5827,7 @@
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
         
-        s2.addSymbol(new AliasSymbol("X", new ExpressionSymbol("expr", QueryParser.getQueryParser().parseExpression("(SELECT e1 FROM m.g1) + (SELECT e3 FROM m.g3)")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s2.addSymbol(new DerivedColumn("X", QueryParser.getQueryParser().parseExpression("(SELECT e1 FROM m.g1) + (SELECT e3 FROM m.g3)"), true)); //$NON-NLS-1$ //$NON-NLS-2$
 
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
@@ -5871,7 +5844,7 @@
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
         
-        s2.addSymbol(new AliasSymbol("X", new ExpressionSymbol("expr", QueryParser.getQueryParser().getQueryParser().parseExpression("length((SELECT e1 FROM m.g1))")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s2.addSymbol(new DerivedColumn("X", QueryParser.getQueryParser().getQueryParser().parseExpression("length((SELECT e1 FROM m.g1))"), true)); //$NON-NLS-1$ //$NON-NLS-2$
 
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
@@ -6043,7 +6016,7 @@
         select.addSymbol(new ElementSymbol("y")); //$NON-NLS-1$
         select.addSymbol(new ElementSymbol("z")); //$NON-NLS-1$
         // The parser hard-codes the name "expr"
-        select.addSymbol(new ExpressionSymbol("expr", expr)); //$NON-NLS-1$
+        select.addSymbol(new DerivedColumn("expr", expr)); //$NON-NLS-1$
         From from = new From();
         from.addGroup(new GroupSymbol("m.g")); //$NON-NLS-1$
         Query q = new Query();
@@ -6070,7 +6043,7 @@
         select.addSymbol(new ElementSymbol("y")); //$NON-NLS-1$
         select.addSymbol(new ElementSymbol("z")); //$NON-NLS-1$
         // The parser hard-codes the name "expr"
-        select.addSymbol(new ExpressionSymbol("expr", expr)); //$NON-NLS-1$
+        select.addSymbol(new DerivedColumn("expr", expr)); //$NON-NLS-1$
         From from = new From();
         from.addGroup(new GroupSymbol("m.g")); //$NON-NLS-1$
         Query q = new Query();
@@ -6118,7 +6091,7 @@
         select.addSymbol(new ElementSymbol("y")); //$NON-NLS-1$
         select.addSymbol(new ElementSymbol("z")); //$NON-NLS-1$
         // The parser hard-codes the name "expr"
-        select.addSymbol(new ExpressionSymbol("expr", expr)); //$NON-NLS-1$
+        select.addSymbol(new DerivedColumn("expr", expr)); //$NON-NLS-1$
         From from = new From();
         from.addGroup(new GroupSymbol("m.g")); //$NON-NLS-1$
         Query q = new Query();
@@ -6144,7 +6117,7 @@
         select.addSymbol(new ElementSymbol("y")); //$NON-NLS-1$
         select.addSymbol(new ElementSymbol("z")); //$NON-NLS-1$
         // The parser hard-codes the name "expr"
-        select.addSymbol(new ExpressionSymbol("expr", expr)); //$NON-NLS-1$
+        select.addSymbol(new DerivedColumn("expr", expr)); //$NON-NLS-1$
         From from = new From();
         from.addGroup(new GroupSymbol("m.g")); //$NON-NLS-1$
         Query q = new Query();
@@ -6299,7 +6272,7 @@
     public void testNationCharString() throws Exception {
         Query query = (Query) QueryParser.getQueryParser().parseCommand("SELECT N'blah' FROM m.g"); //$NON-NLS-1$
         Select select = query.getSelect();
-        ExpressionSymbol s = (ExpressionSymbol) select.getSymbol(0);
+        DerivedColumn s = (DerivedColumn) select.getSymbol(0);
         Constant c = (Constant) s.getExpression();
         assertEquals(c, new Constant("blah")); //$NON-NLS-1$
     }
@@ -6383,7 +6356,7 @@
         From from = new From();
         from.addGroup(g);
         
-        AliasSymbol as = new AliasSymbol("fooAlias", new ElementSymbol("fooKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        DerivedColumn as = new DerivedColumn("fooAlias", new ElementSymbol("fooKey"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 
@@ -6402,7 +6375,7 @@
         From from = new From();
         from.addGroup(g);
         
-        AliasSymbol as = new AliasSymbol("fooAlias", new ElementSymbol("fooKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        DerivedColumn as = new DerivedColumn("fooAlias", new ElementSymbol("fooKey"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 		
@@ -6428,7 +6401,7 @@
                 
         Constant as = new Constant("fooString"); //$NON-NLS-1$
 		Select select = new Select();
-		select.addSymbol(new ExpressionSymbol("expr", as)); //$NON-NLS-1$
+		select.addSymbol(new DerivedColumn("expr", as)); //$NON-NLS-1$
 		
 		Query query = new Query();
 		query.setSelect(select);
@@ -6445,7 +6418,7 @@
         From from = new From();
         from.addGroup(g);
         
-        AliasSymbol as = new AliasSymbol("fooAlias", new ElementSymbol("fooKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        DerivedColumn as = new DerivedColumn("fooAlias", new ElementSymbol("fooKey"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 
@@ -6464,7 +6437,7 @@
         From from = new From();
         from.addGroup(g);
         
-        AliasSymbol as = new AliasSymbol("fooAlias", new ElementSymbol("fooKey")); //$NON-NLS-1$ //$NON-NLS-2$
+        DerivedColumn as = new DerivedColumn("fooAlias", new ElementSymbol("fooKey"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		Select select = new Select();
 		select.addSymbol(as);
 
@@ -6501,7 +6474,7 @@
         
 		Select select = new Select();
 		select.addSymbol(new ElementSymbol("x.y.z.fooKey")); //$NON-NLS-1$
-		AliasSymbol alias = new AliasSymbol("key", new ElementSymbol("x.y.z.key2")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn alias = new DerivedColumn("key", new ElementSymbol("x.y.z.key2"), true); //$NON-NLS-1$ //$NON-NLS-2$
 		select.addSymbol(alias);
 		
 		Criteria crit = new CompareCriteria(new ElementSymbol("x.y.z.fooKey"), SubqueryCompareCriteria.GT, new Constant(new Integer(10))); //$NON-NLS-1$
@@ -6604,7 +6577,7 @@
         from.addGroup(g);
         
         Function f = new Function("+", new Expression[] {new ElementSymbol("x"), new ElementSymbol("y")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 		
@@ -6625,7 +6598,7 @@
         from.addGroup(g);
         
         Function f = new Function("concat", new Expression[] {new ElementSymbol("x", false), new Constant("5")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        ExpressionSymbol es = new ExpressionSymbol("expr", f); //$NON-NLS-1$
+        DerivedColumn es = new DerivedColumn("expr", f); //$NON-NLS-1$
 		Select select = new Select();
 		select.addSymbol(es);
 		
@@ -6734,7 +6707,7 @@
     
     public void testLimit() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);
@@ -6745,7 +6718,7 @@
     
     public void testLimitWithOffset() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);
@@ -6755,7 +6728,7 @@
     
     public void testLimitWithReferences1() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);
@@ -6765,7 +6738,7 @@
     
     public void testLimitWithReferences2() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);
@@ -6775,7 +6748,7 @@
     
     public void testLimitWithReferences3() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);
@@ -6899,7 +6872,7 @@
         String expected = "CREATE PROCEDURE\nBEGIN\nIF(x > 1)\nBEGIN\nSELECT 1;\nEND\nIF(x > 1)\nBEGIN\nSELECT 1;\nEND\nELSE\nBEGIN\nSELECT 1;\nEND\nEND"; //$NON-NLS-1$
         
         Query query = new Query();
-        query.setSelect(new Select(Arrays.asList(new Object[] {new ExpressionSymbol("expr", new Constant(new Integer(1)))}))); //$NON-NLS-1$
+        query.setSelect(new Select(Arrays.asList(new DerivedColumn("expr", new Constant(new Integer(1)))))); //$NON-NLS-1$
         CommandStatement commandStmt = new CommandStatement(query);
         CompareCriteria criteria = new CompareCriteria(new ElementSymbol("x"), CompareCriteria.GT, new Constant(new Integer(1))); //$NON-NLS-1$
         Block block = new Block();
@@ -6929,7 +6902,7 @@
         Function convert = new Function("convert", new Expression[] {new Constant(null), new Constant("blob")}); //$NON-NLS-1$ //$NON-NLS-2$
         Function convert1 = new Function("convert", new Expression[] {new Constant(null), new Constant("clob")}); //$NON-NLS-1$ //$NON-NLS-2$
         Function convert2 = new Function("convert", new Expression[] {new Constant(null), new Constant("xml")}); //$NON-NLS-1$ //$NON-NLS-2$
-        Select select = new Select(Arrays.asList(new Object[] {new ExpressionSymbol("expr", convert), new ExpressionSymbol("expr1", convert1), new ExpressionSymbol("expr2", convert2)})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        Select select = new Select(Arrays.asList(new DerivedColumn("expr", convert), new DerivedColumn("expr1", convert1), new DerivedColumn("expr2", convert2))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         Query query = new Query();
         query.setSelect(select);
         

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -49,7 +49,7 @@
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.lang.SPParameter;
 import com.metamatrix.query.sql.lang.StoredProcedure;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
@@ -462,8 +462,8 @@
         HashMap map = new HashMap();
         map.put(x, y);
         
-    	AggregateSymbol countStar = new AggregateSymbol("agg1", ReservedWords.COUNT, false, null); //$NON-NLS-1$ //$NON-NLS-2$
-    	AggregateSymbol countStar1 = new AggregateSymbol("agg1", ReservedWords.COUNT, false, null); //$NON-NLS-1$ //$NON-NLS-2$
+    	Aggregate countStar = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$ //$NON-NLS-2$
+    	Aggregate countStar1 = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$ //$NON-NLS-2$
     	EvaluateExpressionVisitor.replaceExpressions(countStar, true, null, null);
     	
     	assertEquals(countStar1, countStar);

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -44,7 +44,7 @@
 import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.processor.FakeDataManager;
 import com.metamatrix.query.processor.FakeTupleSource;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
@@ -142,17 +142,17 @@
 		ElementSymbol col2 = new ElementSymbol("col2"); //$NON-NLS-1$
 		col2.setType(Integer.class);
 		outputElements.add(col1);
-		outputElements.add(new AggregateSymbol("countAll", "COUNT", false, null)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("count", "COUNT", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("countDist", "COUNT", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("sum", "SUM", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("sumDist", "SUM", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("avg", "AVG", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("avgDist", "AVG", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("min", "MIN", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("minDist", "MIN", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("max", "MAX", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
-		outputElements.add(new AggregateSymbol("maxDist", "MAX", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("COUNT", false, null)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("COUNT", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("COUNT", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("SUM", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("SUM", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("AVG", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("AVG", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("MIN", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("MIN", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("MAX", false, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+		outputElements.add(new Aggregate("MAX", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
 		node.setElements(outputElements);
 		
 		List groupingElements = new ArrayList();
@@ -186,7 +186,7 @@
         ElementSymbol col2 = new ElementSymbol("col2"); //$NON-NLS-1$
         col2.setType(Integer.class);
         outputElements.add(col1);
-        outputElements.add(new AggregateSymbol("countDist", "COUNT", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("COUNT", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
         node.setElements(outputElements);
         
         List groupingElements = new ArrayList();
@@ -222,7 +222,7 @@
         ElementSymbol col2 = new ElementSymbol("col2"); //$NON-NLS-1$
         col2.setType(Integer.class);
         outputElements.add(col1);
-        outputElements.add(new AggregateSymbol("countDist", "COUNT", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("COUNT", true, col2)); //$NON-NLS-1$ //$NON-NLS-2$
         node.setElements(outputElements);
         
         List groupingElements = new ArrayList();
@@ -254,8 +254,8 @@
         // Set up
         GroupingNode node = new GroupingNode(1);        
         List outputElements = new ArrayList();
-        outputElements.add(new AggregateSymbol("bigSum", "SUM", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
-        outputElements.add(new AggregateSymbol("bigAvg", "AVG", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("SUM", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("AVG", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
         node.setElements(outputElements);
         
         // Set grouping elements to null 
@@ -293,8 +293,8 @@
         GroupingNode node = new GroupingNode(1);        
         List outputElements = new ArrayList();
         outputElements.add(col1);
-        outputElements.add(new AggregateSymbol("bigSum", "SUM", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
-        outputElements.add(new AggregateSymbol("bigAvg", "AVG", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("SUM", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("AVG", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
         node.setElements(outputElements);
         
         // Set grouping elements to null 
@@ -342,9 +342,9 @@
         func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
         
         outputElements.add(col1);
-        outputElements.add(new AggregateSymbol("count", "COUNT", false, func)); //$NON-NLS-1$ //$NON-NLS-2$
-        outputElements.add(new AggregateSymbol("sum", "SUM", false, func)); //$NON-NLS-1$ //$NON-NLS-2$
-        outputElements.add(new AggregateSymbol("sumDist", "SUM", true, func)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("COUNT", false, func)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("SUM", false, func)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("SUM", true, func)); //$NON-NLS-1$ //$NON-NLS-2$
         node.setElements(outputElements);
         
         List groupingElements = new ArrayList();
@@ -389,8 +389,8 @@
         // Set up
         GroupingNode node = new GroupingNode(1);        
         List outputElements = new ArrayList();
-        outputElements.add(new AggregateSymbol("bigSum", "SUM", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
-        outputElements.add(new AggregateSymbol("bigAvg", "AVG", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("SUM", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
+        outputElements.add(new Aggregate("AVG", false, bigDecimal)); //$NON-NLS-1$ //$NON-NLS-2$
         node.setElements(outputElements);
         
         // Set grouping elements to null 

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -45,7 +45,7 @@
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.util.CommandContext;
 
@@ -214,7 +214,7 @@
         FunctionDescriptor fd = FunctionLibraryManager.getFunctionLibrary().findFunction("concat", new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING }); //$NON-NLS-1$
         func.setFunctionDescriptor(fd);
         func.setType(DataTypeManager.DefaultDataClasses.STRING);
-        ExpressionSymbol expr = new ExpressionSymbol("expr", func); //$NON-NLS-1$
+        DerivedColumn expr = new DerivedColumn("expr", func); //$NON-NLS-1$
         List projectElements = new ArrayList();
         projectElements.add(expr);
         
@@ -238,7 +238,7 @@
         FunctionDescriptor fd = FunctionLibraryManager.getFunctionLibrary().findFunction("convert", new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING }); //$NON-NLS-1$
         func.setFunctionDescriptor(fd);
         func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
-        ExpressionSymbol expr = new ExpressionSymbol("expr", func); //$NON-NLS-1$
+        DerivedColumn expr = new DerivedColumn("expr", func); //$NON-NLS-1$
         List projectElements = new ArrayList();
         projectElements.add(expr);
         
@@ -262,7 +262,7 @@
         func.setFunctionDescriptor(desc);
         func.setType(DataTypeManager.DefaultDataClasses.STRING);
         
-        ExpressionSymbol expr = new ExpressionSymbol("expr", func); //$NON-NLS-1$
+        DerivedColumn expr = new DerivedColumn("expr", func); //$NON-NLS-1$
         List projectElements = new ArrayList();
         projectElements.add(expr);
         

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -86,13 +86,13 @@
 import com.metamatrix.query.sql.proc.CreateUpdateProcedureCommand;
 import com.metamatrix.query.sql.proc.LoopStatement;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
 import com.metamatrix.query.sql.symbol.SelectSymbol;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
 import com.metamatrix.query.sql.visitor.ElementCollectorVisitor;
 import com.metamatrix.query.sql.visitor.FunctionCollectorVisitor;
 import com.metamatrix.query.sql.visitor.GroupCollectorVisitor;
@@ -2549,10 +2549,10 @@
             new String[] { "PM1.G1.E2", "PM1.G1.E3" } ); //$NON-NLS-1$ //$NON-NLS-2$
         assertEquals("Resolved string form was incorrect ", sql, resolvedQuery.toString()); //$NON-NLS-1$
         
-        List projSymbols = resolvedQuery.getSelect().getProjectedSymbols();
+        List<DerivedColumn> projSymbols = resolvedQuery.getSelect().getProjectedSymbols();
         assertEquals("Wrong number of projected symbols", 2, projSymbols.size()); //$NON-NLS-1$
-        assertEquals("Wrong type for first symbol", String.class, ((SingleElementSymbol)projSymbols.get(0)).getType()); //$NON-NLS-1$
-        assertEquals("Wrong type for second symbol", Double.class, ((SingleElementSymbol)projSymbols.get(1)).getType()); //$NON-NLS-1$
+        assertEquals("Wrong type for first symbol", String.class, (projSymbols.get(0)).getType()); //$NON-NLS-1$
+        assertEquals("Wrong type for second symbol", Double.class, (projSymbols.get(1)).getType()); //$NON-NLS-1$
     }
 
     public void testLookupFunctionFailBadElement() {     
@@ -3183,7 +3183,7 @@
     public void testNestedUnionQueryWithNull() throws Exception{
         SetQuery command = (SetQuery)helpResolve("SELECT e2, e3 FROM pm1.g1 UNION (SELECT null, e3 FROM pm1.g2 UNION SELECT null, e3 from pm1.g1)"); //$NON-NLS-1$
         
-        assertEquals(DataTypeManager.DefaultDataClasses.INTEGER, ((SingleElementSymbol)command.getProjectedSymbols().get(0)).getType());
+        assertEquals(DataTypeManager.DefaultDataClasses.INTEGER, (command.getProjectedSymbols().get(0)).getType());
     }
     
     public void testSelectIntoNoFrom() {
@@ -3502,7 +3502,7 @@
         QueryResolver.resolveCommand(query, FakeMetadataFactory.exampleBQTCached(), AnalysisRecord.createNonRecordingRecord());
         
         // Check type of resolved null constant
-        SingleElementSymbol symbol = (SingleElementSymbol) query.getSelect().getSymbols().get(0);
+        DerivedColumn symbol = query.getProjectedSymbols().get(0);
         assertNotNull(symbol.getType());
         assertEquals(DataTypeManager.DefaultDataClasses.STRING, symbol.getType());
     }
@@ -3765,9 +3765,9 @@
     }
     
     private void verifyProjectedTypes(Command c, Class[] types) {
-        List projSymbols = c.getProjectedSymbols();
+        List<DerivedColumn> projSymbols = c.getProjectedSymbols();
         for(int i=0; i<projSymbols.size(); i++) {
-            assertEquals("Found type mismatch at column " + i, types[i], ((SingleElementSymbol) projSymbols.get(i)).getType()); //$NON-NLS-1$
+            assertEquals("Found type mismatch at column " + i, types[i], projSymbols.get(i).getType()); //$NON-NLS-1$
         }                
     }
     
@@ -4614,21 +4614,21 @@
     public void testReferenceInSelect() {
     	String sql = "select ?, e1 from pm1.g1"; //$NON-NLS-1$
     	Query command = (Query)helpResolve(sql, FakeMetadataFactory.example1Cached(), null);
-    	assertEquals(DataTypeManager.DefaultDataClasses.STRING, ((SingleElementSymbol)command.getProjectedSymbols().get(0)).getType());
+    	assertEquals(DataTypeManager.DefaultDataClasses.STRING, (command.getProjectedSymbols().get(0)).getType());
     }
     
     public void testReferenceInSelect1() {
     	String sql = "select convert(?, integer), e1 from pm1.g1"; //$NON-NLS-1$
     	
     	Query command = (Query)helpResolve(sql, FakeMetadataFactory.example1Cached(), null);
-    	assertEquals(DataTypeManager.DefaultDataClasses.INTEGER, ((SingleElementSymbol)command.getProjectedSymbols().get(0)).getType());
+    	assertEquals(DataTypeManager.DefaultDataClasses.INTEGER, (command.getProjectedSymbols().get(0)).getType());
     }
     
     public void testUnionWithObjectTypeConversion() {
     	String sql = "select convert(null, xml) from pm1.g1 union all select 1"; //$NON-NLS-1$
     	
     	SetQuery query = (SetQuery)helpResolve(sql, FakeMetadataFactory.example1Cached(), null);
-    	assertEquals(DataTypeManager.DefaultDataClasses.OBJECT, ((SingleElementSymbol)query.getProjectedSymbols().get(0)).getType());
+    	assertEquals(DataTypeManager.DefaultDataClasses.OBJECT, (query.getProjectedSymbols().get(0)).getType());
     }
     
     public void testUnionWithSubQuery() {
@@ -4648,7 +4648,7 @@
 	private void helpTestOrderBy(OrderBy orderBy, int[] expectedPositions) {
 		assertEquals(expectedPositions.length, orderBy.getVariableCount());
         for (int i = 0; i < expectedPositions.length; i++) {
-        	ElementSymbol symbol = (ElementSymbol)orderBy.getVariable(i);
+        	ElementSymbol symbol = (ElementSymbol)orderBy.getSortOrder().get(0).getSortKey();
         	TempMetadataID tid = (TempMetadataID)symbol.getMetadataID();
         	assertEquals(expectedPositions[i], tid.getPosition());
         }
@@ -4672,7 +4672,7 @@
     }
     
     public void testSPOutParamWithExec() {
-    	StoredProcedure proc = (StoredProcedure)helpResolve("exec pm2.spTest8(1)", FakeMetadataFactory.exampleBQTCached(), null);
+    	StoredProcedure proc = (StoredProcedure)helpResolve("exec pm2.spTest8(1)", FakeMetadataFactory.exampleBQTCached(), null); //$NON-NLS-1$
     	assertEquals(2, proc.getProjectedSymbols().size());
     }
 
@@ -4681,17 +4681,17 @@
      * That hack is handled by the PreparedStatementRequest
      */
     public void testSPOutParamWithCallableStatement() {
-    	StoredProcedure proc = (StoredProcedure)helpResolve("{call pm2.spTest8(1)}", FakeMetadataFactory.exampleBQTCached(), null);
+    	StoredProcedure proc = (StoredProcedure)helpResolve("{call pm2.spTest8(1)}", FakeMetadataFactory.exampleBQTCached(), null); //$NON-NLS-1$
     	assertEquals(3, proc.getProjectedSymbols().size());
     }
     
     public void testProcRelationalWithOutParam() {
-    	Query proc = (Query)helpResolve("select * from pm2.spTest8 where inkey = 1", FakeMetadataFactory.exampleBQTCached(), null);
+    	Query proc = (Query)helpResolve("select * from pm2.spTest8 where inkey = 1", FakeMetadataFactory.exampleBQTCached(), null); //$NON-NLS-1$
     	assertEquals(3, proc.getProjectedSymbols().size());
     }
     
     public void testSPReturnParamWithNoResultSet() {
-    	StoredProcedure proc = (StoredProcedure)helpResolve("exec pm4.spTest9(1)", FakeMetadataFactory.exampleBQTCached(), null);
+    	StoredProcedure proc = (StoredProcedure)helpResolve("exec pm4.spTest9(1)", FakeMetadataFactory.exampleBQTCached(), null); //$NON-NLS-1$
     	assertEquals(1, proc.getProjectedSymbols().size());
     }
     

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestOrderByRewrite.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestOrderByRewrite.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestOrderByRewrite.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -39,7 +39,7 @@
 import com.metamatrix.query.sql.lang.OrderBy;
 import com.metamatrix.query.sql.lang.Query;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.visitor.ElementCollectorVisitor;
 import com.metamatrix.query.sql.visitor.ExpressionSymbolCollector;
 import com.metamatrix.query.unittest.FakeMetadataFactory;
@@ -89,7 +89,7 @@
         assertEquals("Wrong number of Symbols: ", functionsNames.length, symbols.size()); //$NON-NLS-1$
 
         for (int i = 0; i < symbols.size(); i++) {
-            ExpressionSymbol symbol = (ExpressionSymbol)symbols.get(i);
+            DerivedColumn symbol = (DerivedColumn)symbols.get(i);
             assertEquals("Expression Symbols does not match: ", functionsNames[i], symbol.toString()); //$NON-NLS-1$            
         }
     }

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -20,8 +20,8 @@
  * 02110-1301 USA.
  */
 
-package com.metamatrix.query.rewriter;
-
+package com.metamatrix.query.rewriter;
+
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Arrays;
@@ -61,7 +61,7 @@
 import com.metamatrix.query.sql.lang.Update;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.SingleElementSymbol;
@@ -71,388 +71,388 @@
 import com.metamatrix.query.unittest.FakeMetadataObject;
 import com.metamatrix.query.util.CommandContext;
 import com.metamatrix.query.util.ContextProperties;
-
-public class TestQueryRewriter extends TestCase {
-
-    private static final String TRUE_STR = "1 = 1"; //$NON-NLS-1$
-    private static final String FALSE_STR = "1 = 0"; //$NON-NLS-1$
-
-    // ################################## FRAMEWORK ################################
-    
-    public TestQueryRewriter(String name) { 
-        super(name);
-    }
-
-    // ################################## TEST HELPERS ################################
-    
-    private Criteria parseCriteria(String critStr, QueryMetadataInterface metadata) {
-        try {
-            Criteria crit = QueryParser.getQueryParser().parseCriteria(critStr);
-            
-            // resolve against metadata
-            QueryResolver.resolveCriteria(crit, metadata);
-            
-            return crit;
-        } catch(MetaMatrixException e) {
-            throw new RuntimeException(e);
-        }   
-    }
-    
-    private Criteria helpTestRewriteCriteria(String original, String expected) {
-        try {
-            return helpTestRewriteCriteria(original, expected, false);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        } 
-    }   
-    
-    private Criteria helpTestRewriteCriteria(String original, String expected, boolean rewrite) throws QueryResolverException, QueryMetadataException, MetaMatrixComponentException, QueryValidatorException {
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria expectedCrit = parseCriteria(expected, metadata);
-        if (rewrite) {
-            QueryResolver.resolveCriteria(expectedCrit, metadata);
-            expectedCrit = QueryRewriter.rewriteCriteria(expectedCrit, null, null, metadata);
-        }
-        return helpTestRewriteCriteria(original, expectedCrit, metadata);
-    }
-
-    private Criteria helpTestRewriteCriteria(String original, Criteria expectedCrit, QueryMetadataInterface metadata) {
-        Criteria origCrit = parseCriteria(original, metadata);
-        
-        Criteria actual = null;
-        // rewrite
-        try { 
-            actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
-        } catch(QueryValidatorException e) { 
-            e.printStackTrace();
-            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        return actual;
-    }    
-    
-	private String getReWrittenProcedure(String procedure, String userUpdateStr, String procedureType) {
-        QueryMetadataInterface metadata = FakeMetadataFactory.exampleUpdateProc(procedureType, procedure);
-
-        try {
-            Command userCommand = QueryParser.getQueryParser().parseCommand(userUpdateStr);       
-            QueryResolver.resolveCommand(userCommand, metadata);
-    		QueryRewriter.rewrite(userCommand, null, metadata, null);
-    		return userCommand.getSubCommands().get(0).toString();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-	}
-	
-	private void helpFailUpdateProcedure(String procedure, String userUpdateStr, String procedureType) {
-        QueryMetadataInterface metadata = FakeMetadataFactory.exampleUpdateProc(procedureType, procedure);
-
-        Command userCommand = null;       
-        try {
-            QueryParser parser = new QueryParser();
-            userCommand = parser.parseCommand(userUpdateStr);
-            QueryResolver.resolveCommand(userCommand, metadata);            
-        } catch(MetaMatrixException e) {
-            e.printStackTrace();
-			fail("Exception during parsing/resolution (" + e.getClass().getName() + "): " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-		QueryValidatorException exception = null;
-        try {		
-			QueryRewriter.rewrite(userCommand, null, metadata, null);
-        } catch(QueryValidatorException e) {
-        	exception = e;
-        }
-
-		assertNotNull("Expected a QueryValidatorException but got none.", exception); //$NON-NLS-1$
-	}
-
-    private Command helpTestRewriteCommand(String original, String expected) { 
-        try {
-            return helpTestRewriteCommand(original, expected, FakeMetadataFactory.example1Cached());
-        } catch(MetaMatrixException e) { 
-            throw new MetaMatrixRuntimeException(e);
-        }
-    }
-    
-    private Command helpTestRewriteCommand(String original, String expected, QueryMetadataInterface metadata) throws MetaMatrixException { 
-        Command command = QueryParser.getQueryParser().parseCommand(original);            
-        QueryResolver.resolveCommand(command, metadata);
-        Command rewriteCommand = QueryRewriter.rewrite(command, null, metadata, null);
-        assertEquals("Rewritten command was not expected", expected, rewriteCommand.toString()); //$NON-NLS-1$
-        return rewriteCommand;
-    }
-    
-    public void testRewriteUnknown() {
-        helpTestRewriteCriteria("pm1.g1.e1 = '1' and '1' = convert(null, string)", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteUnknown1() {
-        helpTestRewriteCriteria("pm1.g1.e1 = '1' or '1' = convert(null, string)", "pm1.g1.e1 = '1'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteUnknown2() {
-        helpTestRewriteCriteria("not('1' = convert(null, string))", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteUnknown3() {
-        helpTestRewriteCriteria("pm1.g1.e1 like convert(null, string))", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteUnknown4() {
-        helpTestRewriteCriteria("null in ('a', 'b', 'c')", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteUnknown5() {
-        helpTestRewriteCriteria("(null <> null) and 1 = 0", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteUnknown6() {
-        helpTestRewriteCriteria("not(pm1.g1.e1 = '1' and '1' = convert(null, string))", "NOT ((pm1.g1.e1 = '1') and (NULL <> NULL))"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-        
-    public void testRewriteUnknown7() {
-        helpTestRewriteCriteria("not(pm1.g1.e1 = '1' or '1' = convert(null, string))", "NOT ((pm1.g1.e1 = '1') or (NULL <> NULL))"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteUnknown8() {
-        helpTestRewriteCriteria("pm1.g1.e1 in (2, null)", "pm1.g1.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$ 
-    }
-    
-    public void testRewriteInCriteriaWithRepeats() {
-        helpTestRewriteCriteria("pm1.g1.e1 in ('1', '1', '2')", "pm1.g1.e1 IN ('1', '2')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteInCriteriaWithSingleValue() {
-        helpTestRewriteCriteria("pm1.g1.e1 in ('1')", "pm1.g1.e1 = '1'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteInCriteriaWithSingleValue1() {
-        helpTestRewriteCriteria("pm1.g1.e1 not in ('1')", "pm1.g1.e1 != '1'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteInCriteriaWithNoValues() throws Exception {
-        Criteria crit = new SetCriteria(new ElementSymbol("e1"), Collections.EMPTY_LIST); //$NON-NLS-1$
-        
-        Criteria actual = QueryRewriter.rewriteCriteria(crit, null, null, null);
-        
-        assertEquals(QueryRewriter.FALSE_CRITERIA, actual);
-    }
-        
-    public void testRewriteBetweenCriteria1() {
-        helpTestRewriteCriteria("pm1.g1.e1 BETWEEN 1000 AND 2000", "(pm1.g1.e1 >= '1000') AND (pm1.g1.e1 <= '2000')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteBetweenCriteria2() {
-        helpTestRewriteCriteria("pm1.g1.e1 NOT BETWEEN 1000 AND 2000", "(pm1.g1.e1 < '1000') OR (pm1.g1.e1 > '2000')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCrit1() {
-        helpTestRewriteCriteria("concat('a','b') = 'ab'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCrit2() {
-        helpTestRewriteCriteria("'x' = pm1.g1.e1", "(pm1.g1.e1 = 'x')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCrit3() {
-        helpTestRewriteCriteria("pm1.g1.e1 = convert('a', string)", "pm1.g1.e1 = 'a'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCrit4() {
-        helpTestRewriteCriteria("pm1.g1.e1 = CONVERT('a', string)", "pm1.g1.e1 = 'a'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCrit5() {
-        helpTestRewriteCriteria("pm1.g1.e1 in ('a')", "pm1.g1.e1 = 'a'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCrit6() {
-        helpTestRewriteCriteria("1 = convert(pm1.g1.e1,integer) + 10", "convert(pm1.g1.e1, integer) = -9"); //$NON-NLS-1$ //$NON-NLS-2$
-    } 
-    
-    public void testRewriteCrit7() {
-        helpTestRewriteCriteria("((pm1.g1.e1 = 1) and (pm1.g1.e1 = 1))", "pm1.g1.e1 = '1'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteMatchCritEscapeChar1() {
-        helpTestRewriteCriteria("pm1.g1.e1 LIKE 'x_' ESCAPE '\\'", "pm1.g1.e1 LIKE 'x_'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteMatchCritEscapeChar2() {
-        helpTestRewriteCriteria("pm1.g1.e1 LIKE '#%x' ESCAPE '#'", "pm1.g1.e1 LIKE '#%x' ESCAPE '#'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteMatchCritEscapeChar3() {
-        helpTestRewriteCriteria("pm1.g1.e1 LIKE '#%x'", "pm1.g1.e1 LIKE '#%x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteMatchCritEscapeChar4() {
-        helpTestRewriteCriteria("pm1.g1.e1 LIKE pm1.g1.e1 ESCAPE '#'", "pm1.g1.e1 LIKE pm1.g1.e1 ESCAPE '#'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteMatchCritEscapeChar5() throws Exception {
-        MatchCriteria mcrit = new MatchCriteria(new ElementSymbol("pm1.g1.e1"), new Constant(null, DataTypeManager.DefaultDataClasses.STRING), '#'); //$NON-NLS-1$
-        Criteria expected = QueryRewriter.UNKNOWN_CRITERIA; 
-                
-        Object actual = QueryRewriter.rewriteCriteria(mcrit, null, null, null); 
-        assertEquals("Did not get expected rewritten criteria", expected, actual); //$NON-NLS-1$
-    }
-    
-    public void testRewriteMatchCrit1() {
-        helpTestRewriteCriteria("pm1.g1.e1 LIKE 'x' ESCAPE '\\'", "pm1.g1.e1 = 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteMatchCrit2() {
-        helpTestRewriteCriteria("pm1.g1.e1 NOT LIKE 'x'", "pm1.g1.e1 <> 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteMatchCrit3() {
-        helpTestRewriteCriteria("pm1.g1.e1 NOT LIKE '%'", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCritTimestampCreate1() {
-        helpTestRewriteCriteria("timestampCreate(pm3.g1.e2, pm3.g1.e3) = {ts'2004-11-23 09:25:00'}", "(pm3.g1.e2 = {d'2004-11-23'}) AND (pm3.g1.e3 = {t'09:25:00'})"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritTimestampCreate2() {
-        helpTestRewriteCriteria("{ts'2004-11-23 09:25:00'} = timestampCreate(pm3.g1.e2, pm3.g1.e3)", "(pm3.g1.e2 = {d'2004-11-23'}) AND (pm3.g1.e3 = {t'09:25:00'})"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritSwap1() {
-        helpTestRewriteCriteria("'x' = pm1.g1.e1", "pm1.g1.e1 = 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritSwap2() {
-        helpTestRewriteCriteria("'x' <> pm1.g1.e1", "pm1.g1.e1 <> 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritSwap3() {
-        helpTestRewriteCriteria("'x' < pm1.g1.e1", "pm1.g1.e1 > 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritSwap4() {
-        helpTestRewriteCriteria("'x' <= pm1.g1.e1", "pm1.g1.e1 >= 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritSwap5() {
-        helpTestRewriteCriteria("'x' > pm1.g1.e1", "pm1.g1.e1 < 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritSwap6() {
-        helpTestRewriteCriteria("'x' >= pm1.g1.e1", "pm1.g1.e1 <= 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_op1() {
-        helpTestRewriteCriteria("pm1.g1.e2 + 5 = 10", "pm1.g1.e2 = 5"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_op2() {
-        helpTestRewriteCriteria("pm1.g1.e2 - 5 = 10", "pm1.g1.e2 = 15"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_op3() {
-        helpTestRewriteCriteria("pm1.g1.e2 * 5 = 10", "pm1.g1.e2 = 2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_op4() {
-        helpTestRewriteCriteria("pm1.g1.e2 / 5 = 10", "pm1.g1.e2 = 50"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_signFlip1() {
-        helpTestRewriteCriteria("pm1.g1.e2 * -5 > 10", "pm1.g1.e2 < -2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_signFlip2() {
-        helpTestRewriteCriteria("pm1.g1.e2 * -5 >= 10", "pm1.g1.e2 <= -2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCritExpr_signFlip3() {
-        helpTestRewriteCriteria("pm1.g1.e2 * -5 < 10", "pm1.g1.e2 > -2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_signFlip4() {
-        helpTestRewriteCriteria("pm1.g1.e2 * -5 <= 10", "pm1.g1.e2 >= -2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCritExpr_backwards1() {
-        helpTestRewriteCriteria("5 + pm1.g1.e2 <= 10", "pm1.g1.e2 <= 5"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_backwards2() {
-        helpTestRewriteCriteria("-5 * pm1.g1.e2 <= 10", "pm1.g1.e2 >= -2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCritExpr_unhandled1() {
-        helpTestRewriteCriteria("5 / pm1.g1.e2 <= 10", "5 / pm1.g1.e2 <= 10"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCritExpr_unhandled2() {
-        helpTestRewriteCriteria("5 - pm1.g1.e2 <= 10", "5 - pm1.g1.e2 <= 10"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCrit_parseDate() {
-        helpTestRewriteCriteria("PARSEDATE(pm3.g1.e1, 'yyyyMMdd') = {d'2003-05-01'}", //$NON-NLS-1$
-                                "pm3.g1.e1 = '20030501'" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_parseDate1() {
-        helpTestRewriteCriteria("PARSEDATE(pm3.g1.e1, 'yyyyMM') = {d'2003-05-01'}", //$NON-NLS-1$
-                                "pm3.g1.e1 = '200305'" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_parseDate2() {
-        helpTestRewriteCriteria("PARSEDATE(pm3.g1.e1, 'yyyyMM') = {d'2003-05-02'}", //$NON-NLS-1$
-                                "1 = 0" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_invalidParseDate() {
-        QueryMetadataInterface metadata = FakeMetadataFactory.example1Cached();
-        Criteria origCrit = parseCriteria("PARSEDATE(pm3.g1.e1, '''') = {d'2003-05-01'}", metadata); //$NON-NLS-1$
-        
-        try { 
-            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            fail("Expected failure"); //$NON-NLS-1$
-        } catch(QueryValidatorException e) { 
-            assertEquals("Error simplifying criteria: PARSEDATE(pm3.g1.e1, '''') = {d'2003-05-01'}", e.getMessage());     //$NON-NLS-1$
-        }
-    }
-    
-    public void testRewriteCrit_parseTime() {
-        helpTestRewriteCriteria("PARSETIME(pm3.g1.e1, 'HH mm ss') = {t'13:25:04'}", //$NON-NLS-1$
-                                "pm3.g1.e1 = '13 25 04'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseTimestamp() {
-        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') = {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
-                                "1 = 0" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_parseTimestamp1() {
-        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') = {ts'2003-01-01 00:25:00.0'}", //$NON-NLS-1$
-                                "pm3.g1.e1 = '2003 01 25'" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_parseTimestamp2() {
-        helpTestRewriteCriteria("PARSETimestamp(CONVERT(pm3.g1.e2, string), 'yyyy-MM-dd') = {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
-                                "1 = 0" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseTimestamp3() {
-        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') <> {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
-                                "1 = 1" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_parseTimestamp4() {
-        helpTestRewriteCriteria("PARSETimestamp(CONVERT(pm3.g1.e2, string), 'yyyy-MM-dd') = {ts'2003-05-01 00:00:00.0'}", //$NON-NLS-1$
-                                "pm3.g1.e2 = {d'2003-05-01'}" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_parseTimestamp_notEquality() {
-        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') > {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
-                                "PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') > {ts'2003-05-01 13:25:04.5'}" );         //$NON-NLS-1$
+
+public class TestQueryRewriter extends TestCase {
+
+    private static final String TRUE_STR = "1 = 1"; //$NON-NLS-1$
+    private static final String FALSE_STR = "1 = 0"; //$NON-NLS-1$
+
+    // ################################## FRAMEWORK ################################
+    
+    public TestQueryRewriter(String name) { 
+        super(name);
     }
+
+    // ################################## TEST HELPERS ################################
     
+    private Criteria parseCriteria(String critStr, QueryMetadataInterface metadata) {
+        try {
+            Criteria crit = QueryParser.getQueryParser().parseCriteria(critStr);
+            
+            // resolve against metadata
+            QueryResolver.resolveCriteria(crit, metadata);
+            
+            return crit;
+        } catch(MetaMatrixException e) {
+            throw new RuntimeException(e);
+        }   
+    }
+    
+    private Criteria helpTestRewriteCriteria(String original, String expected) {
+        try {
+            return helpTestRewriteCriteria(original, expected, false);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } 
+    }   
+    
+    private Criteria helpTestRewriteCriteria(String original, String expected, boolean rewrite) throws QueryResolverException, QueryMetadataException, MetaMatrixComponentException, QueryValidatorException {
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria expectedCrit = parseCriteria(expected, metadata);
+        if (rewrite) {
+            QueryResolver.resolveCriteria(expectedCrit, metadata);
+            expectedCrit = QueryRewriter.rewriteCriteria(expectedCrit, null, null, metadata);
+        }
+        return helpTestRewriteCriteria(original, expectedCrit, metadata);
+    }
+
+    private Criteria helpTestRewriteCriteria(String original, Criteria expectedCrit, QueryMetadataInterface metadata) {
+        Criteria origCrit = parseCriteria(original, metadata);
+        
+        Criteria actual = null;
+        // rewrite
+        try { 
+            actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
+        } catch(QueryValidatorException e) { 
+            e.printStackTrace();
+            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return actual;
+    }    
+    
+	private String getReWrittenProcedure(String procedure, String userUpdateStr, String procedureType) {
+        QueryMetadataInterface metadata = FakeMetadataFactory.exampleUpdateProc(procedureType, procedure);
+
+        try {
+            Command userCommand = QueryParser.getQueryParser().parseCommand(userUpdateStr);       
+            QueryResolver.resolveCommand(userCommand, metadata);
+    		QueryRewriter.rewrite(userCommand, null, metadata, null);
+    		return userCommand.getSubCommands().get(0).toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+	}
+	
+	private void helpFailUpdateProcedure(String procedure, String userUpdateStr, String procedureType) {
+        QueryMetadataInterface metadata = FakeMetadataFactory.exampleUpdateProc(procedureType, procedure);
+
+        Command userCommand = null;       
+        try {
+            QueryParser parser = new QueryParser();
+            userCommand = parser.parseCommand(userUpdateStr);
+            QueryResolver.resolveCommand(userCommand, metadata);            
+        } catch(MetaMatrixException e) {
+            e.printStackTrace();
+			fail("Exception during parsing/resolution (" + e.getClass().getName() + "): " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+		QueryValidatorException exception = null;
+        try {		
+			QueryRewriter.rewrite(userCommand, null, metadata, null);
+        } catch(QueryValidatorException e) {
+        	exception = e;
+        }
+
+		assertNotNull("Expected a QueryValidatorException but got none.", exception); //$NON-NLS-1$
+	}
+
+    private Command helpTestRewriteCommand(String original, String expected) { 
+        try {
+            return helpTestRewriteCommand(original, expected, FakeMetadataFactory.example1Cached());
+        } catch(MetaMatrixException e) { 
+            throw new MetaMatrixRuntimeException(e);
+        }
+    }
+    
+    private Command helpTestRewriteCommand(String original, String expected, QueryMetadataInterface metadata) throws MetaMatrixException { 
+        Command command = QueryParser.getQueryParser().parseCommand(original);            
+        QueryResolver.resolveCommand(command, metadata);
+        Command rewriteCommand = QueryRewriter.rewrite(command, null, metadata, null);
+        assertEquals("Rewritten command was not expected", expected, rewriteCommand.toString()); //$NON-NLS-1$
+        return rewriteCommand;
+    }
+    
+    public void testRewriteUnknown() {
+        helpTestRewriteCriteria("pm1.g1.e1 = '1' and '1' = convert(null, string)", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteUnknown1() {
+        helpTestRewriteCriteria("pm1.g1.e1 = '1' or '1' = convert(null, string)", "pm1.g1.e1 = '1'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteUnknown2() {
+        helpTestRewriteCriteria("not('1' = convert(null, string))", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteUnknown3() {
+        helpTestRewriteCriteria("pm1.g1.e1 like convert(null, string))", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteUnknown4() {
+        helpTestRewriteCriteria("null in ('a', 'b', 'c')", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteUnknown5() {
+        helpTestRewriteCriteria("(null <> null) and 1 = 0", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteUnknown6() {
+        helpTestRewriteCriteria("not(pm1.g1.e1 = '1' and '1' = convert(null, string))", "NOT ((pm1.g1.e1 = '1') and (NULL <> NULL))"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+        
+    public void testRewriteUnknown7() {
+        helpTestRewriteCriteria("not(pm1.g1.e1 = '1' or '1' = convert(null, string))", "NOT ((pm1.g1.e1 = '1') or (NULL <> NULL))"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteUnknown8() {
+        helpTestRewriteCriteria("pm1.g1.e1 in (2, null)", "pm1.g1.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$ 
+    }
+    
+    public void testRewriteInCriteriaWithRepeats() {
+        helpTestRewriteCriteria("pm1.g1.e1 in ('1', '1', '2')", "pm1.g1.e1 IN ('1', '2')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteInCriteriaWithSingleValue() {
+        helpTestRewriteCriteria("pm1.g1.e1 in ('1')", "pm1.g1.e1 = '1'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteInCriteriaWithSingleValue1() {
+        helpTestRewriteCriteria("pm1.g1.e1 not in ('1')", "pm1.g1.e1 != '1'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteInCriteriaWithNoValues() throws Exception {
+        Criteria crit = new SetCriteria(new ElementSymbol("e1"), Collections.EMPTY_LIST); //$NON-NLS-1$
+        
+        Criteria actual = QueryRewriter.rewriteCriteria(crit, null, null, null);
+        
+        assertEquals(QueryRewriter.FALSE_CRITERIA, actual);
+    }
+        
+    public void testRewriteBetweenCriteria1() {
+        helpTestRewriteCriteria("pm1.g1.e1 BETWEEN 1000 AND 2000", "(pm1.g1.e1 >= '1000') AND (pm1.g1.e1 <= '2000')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteBetweenCriteria2() {
+        helpTestRewriteCriteria("pm1.g1.e1 NOT BETWEEN 1000 AND 2000", "(pm1.g1.e1 < '1000') OR (pm1.g1.e1 > '2000')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCrit1() {
+        helpTestRewriteCriteria("concat('a','b') = 'ab'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCrit2() {
+        helpTestRewriteCriteria("'x' = pm1.g1.e1", "(pm1.g1.e1 = 'x')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCrit3() {
+        helpTestRewriteCriteria("pm1.g1.e1 = convert('a', string)", "pm1.g1.e1 = 'a'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCrit4() {
+        helpTestRewriteCriteria("pm1.g1.e1 = CONVERT('a', string)", "pm1.g1.e1 = 'a'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCrit5() {
+        helpTestRewriteCriteria("pm1.g1.e1 in ('a')", "pm1.g1.e1 = 'a'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCrit6() {
+        helpTestRewriteCriteria("1 = convert(pm1.g1.e1,integer) + 10", "convert(pm1.g1.e1, integer) = -9"); //$NON-NLS-1$ //$NON-NLS-2$
+    } 
+    
+    public void testRewriteCrit7() {
+        helpTestRewriteCriteria("((pm1.g1.e1 = 1) and (pm1.g1.e1 = 1))", "pm1.g1.e1 = '1'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteMatchCritEscapeChar1() {
+        helpTestRewriteCriteria("pm1.g1.e1 LIKE 'x_' ESCAPE '\\'", "pm1.g1.e1 LIKE 'x_'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteMatchCritEscapeChar2() {
+        helpTestRewriteCriteria("pm1.g1.e1 LIKE '#%x' ESCAPE '#'", "pm1.g1.e1 LIKE '#%x' ESCAPE '#'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteMatchCritEscapeChar3() {
+        helpTestRewriteCriteria("pm1.g1.e1 LIKE '#%x'", "pm1.g1.e1 LIKE '#%x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteMatchCritEscapeChar4() {
+        helpTestRewriteCriteria("pm1.g1.e1 LIKE pm1.g1.e1 ESCAPE '#'", "pm1.g1.e1 LIKE pm1.g1.e1 ESCAPE '#'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteMatchCritEscapeChar5() throws Exception {
+        MatchCriteria mcrit = new MatchCriteria(new ElementSymbol("pm1.g1.e1"), new Constant(null, DataTypeManager.DefaultDataClasses.STRING), '#'); //$NON-NLS-1$
+        Criteria expected = QueryRewriter.UNKNOWN_CRITERIA; 
+                
+        Object actual = QueryRewriter.rewriteCriteria(mcrit, null, null, null); 
+        assertEquals("Did not get expected rewritten criteria", expected, actual); //$NON-NLS-1$
+    }
+    
+    public void testRewriteMatchCrit1() {
+        helpTestRewriteCriteria("pm1.g1.e1 LIKE 'x' ESCAPE '\\'", "pm1.g1.e1 = 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteMatchCrit2() {
+        helpTestRewriteCriteria("pm1.g1.e1 NOT LIKE 'x'", "pm1.g1.e1 <> 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteMatchCrit3() {
+        helpTestRewriteCriteria("pm1.g1.e1 NOT LIKE '%'", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCritTimestampCreate1() {
+        helpTestRewriteCriteria("timestampCreate(pm3.g1.e2, pm3.g1.e3) = {ts'2004-11-23 09:25:00'}", "(pm3.g1.e2 = {d'2004-11-23'}) AND (pm3.g1.e3 = {t'09:25:00'})"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritTimestampCreate2() {
+        helpTestRewriteCriteria("{ts'2004-11-23 09:25:00'} = timestampCreate(pm3.g1.e2, pm3.g1.e3)", "(pm3.g1.e2 = {d'2004-11-23'}) AND (pm3.g1.e3 = {t'09:25:00'})"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritSwap1() {
+        helpTestRewriteCriteria("'x' = pm1.g1.e1", "pm1.g1.e1 = 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritSwap2() {
+        helpTestRewriteCriteria("'x' <> pm1.g1.e1", "pm1.g1.e1 <> 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritSwap3() {
+        helpTestRewriteCriteria("'x' < pm1.g1.e1", "pm1.g1.e1 > 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritSwap4() {
+        helpTestRewriteCriteria("'x' <= pm1.g1.e1", "pm1.g1.e1 >= 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritSwap5() {
+        helpTestRewriteCriteria("'x' > pm1.g1.e1", "pm1.g1.e1 < 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritSwap6() {
+        helpTestRewriteCriteria("'x' >= pm1.g1.e1", "pm1.g1.e1 <= 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_op1() {
+        helpTestRewriteCriteria("pm1.g1.e2 + 5 = 10", "pm1.g1.e2 = 5"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_op2() {
+        helpTestRewriteCriteria("pm1.g1.e2 - 5 = 10", "pm1.g1.e2 = 15"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_op3() {
+        helpTestRewriteCriteria("pm1.g1.e2 * 5 = 10", "pm1.g1.e2 = 2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_op4() {
+        helpTestRewriteCriteria("pm1.g1.e2 / 5 = 10", "pm1.g1.e2 = 50"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_signFlip1() {
+        helpTestRewriteCriteria("pm1.g1.e2 * -5 > 10", "pm1.g1.e2 < -2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_signFlip2() {
+        helpTestRewriteCriteria("pm1.g1.e2 * -5 >= 10", "pm1.g1.e2 <= -2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCritExpr_signFlip3() {
+        helpTestRewriteCriteria("pm1.g1.e2 * -5 < 10", "pm1.g1.e2 > -2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_signFlip4() {
+        helpTestRewriteCriteria("pm1.g1.e2 * -5 <= 10", "pm1.g1.e2 >= -2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCritExpr_backwards1() {
+        helpTestRewriteCriteria("5 + pm1.g1.e2 <= 10", "pm1.g1.e2 <= 5"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_backwards2() {
+        helpTestRewriteCriteria("-5 * pm1.g1.e2 <= 10", "pm1.g1.e2 >= -2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCritExpr_unhandled1() {
+        helpTestRewriteCriteria("5 / pm1.g1.e2 <= 10", "5 / pm1.g1.e2 <= 10"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCritExpr_unhandled2() {
+        helpTestRewriteCriteria("5 - pm1.g1.e2 <= 10", "5 - pm1.g1.e2 <= 10"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCrit_parseDate() {
+        helpTestRewriteCriteria("PARSEDATE(pm3.g1.e1, 'yyyyMMdd') = {d'2003-05-01'}", //$NON-NLS-1$
+                                "pm3.g1.e1 = '20030501'" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_parseDate1() {
+        helpTestRewriteCriteria("PARSEDATE(pm3.g1.e1, 'yyyyMM') = {d'2003-05-01'}", //$NON-NLS-1$
+                                "pm3.g1.e1 = '200305'" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_parseDate2() {
+        helpTestRewriteCriteria("PARSEDATE(pm3.g1.e1, 'yyyyMM') = {d'2003-05-02'}", //$NON-NLS-1$
+                                "1 = 0" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_invalidParseDate() {
+        QueryMetadataInterface metadata = FakeMetadataFactory.example1Cached();
+        Criteria origCrit = parseCriteria("PARSEDATE(pm3.g1.e1, '''') = {d'2003-05-01'}", metadata); //$NON-NLS-1$
+        
+        try { 
+            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            fail("Expected failure"); //$NON-NLS-1$
+        } catch(QueryValidatorException e) { 
+            assertEquals("Error simplifying criteria: PARSEDATE(pm3.g1.e1, '''') = {d'2003-05-01'}", e.getMessage());     //$NON-NLS-1$
+        }
+    }
+    
+    public void testRewriteCrit_parseTime() {
+        helpTestRewriteCriteria("PARSETIME(pm3.g1.e1, 'HH mm ss') = {t'13:25:04'}", //$NON-NLS-1$
+                                "pm3.g1.e1 = '13 25 04'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseTimestamp() {
+        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') = {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
+                                "1 = 0" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_parseTimestamp1() {
+        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') = {ts'2003-01-01 00:25:00.0'}", //$NON-NLS-1$
+                                "pm3.g1.e1 = '2003 01 25'" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_parseTimestamp2() {
+        helpTestRewriteCriteria("PARSETimestamp(CONVERT(pm3.g1.e2, string), 'yyyy-MM-dd') = {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
+                                "1 = 0" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseTimestamp3() {
+        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') <> {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
+                                "1 = 1" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_parseTimestamp4() {
+        helpTestRewriteCriteria("PARSETimestamp(CONVERT(pm3.g1.e2, string), 'yyyy-MM-dd') = {ts'2003-05-01 00:00:00.0'}", //$NON-NLS-1$
+                                "pm3.g1.e2 = {d'2003-05-01'}" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_parseTimestamp_notEquality() {
+        helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') > {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
+                                "PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') > {ts'2003-05-01 13:25:04.5'}" );         //$NON-NLS-1$
+    }
+    
     public void testRewriteCrit_parseTimestamp_decompose() {
         helpTestRewriteCriteria("PARSETIMESTAMP(CONCAT(FORMATDATE(pm3.g1.e2, 'yyyyMMdd'), FORMATTIME(pm3.g1.e3, 'HHmmss')), 'yyyyMMddHHmmss') = PARSETIMESTAMP('19690920183045', 'yyyyMMddHHmmss')", //$NON-NLS-1$
         "(pm3.g1.e2 = {d'1969-09-20'}) AND (pm3.g1.e3 = {t'18:30:45'})" );         //$NON-NLS-1$
@@ -461,1639 +461,1639 @@
     public void testRewriteCrit_timestampCreate_decompose() {
         helpTestRewriteCriteria("timestampCreate(pm3.g1.e2, pm3.g1.e3) = PARSETIMESTAMP('19690920183045', 'yyyyMMddHHmmss')", //$NON-NLS-1$
         "(pm3.g1.e2 = {d'1969-09-20'}) AND (pm3.g1.e3 = {t'18:30:45'})" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseInteger() {
-        helpTestRewriteCriteria("parseInteger(pm1.g1.e1, '#,##0') = 1234", //$NON-NLS-1$
-                                "pm1.g1.e1 = '1,234'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseLong() {
-        helpTestRewriteCriteria("parseLong(pm1.g1.e1, '#,##0') = convert(1234, long)", //$NON-NLS-1$
-                                "pm1.g1.e1 = '1,234'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseBigInteger() {
-        helpTestRewriteCriteria("parseBigInteger(pm1.g1.e1, '#,##0') = convert(1234, biginteger)", //$NON-NLS-1$
-                                "pm1.g1.e1 = '1,234'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseFloat() {
-        helpTestRewriteCriteria("parseFloat(pm1.g1.e1, '#,##0.###') = convert(1234.1234, float)", //$NON-NLS-1$
-                                "pm1.g1.e1 = '1,234.123'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseDouble() {
-        helpTestRewriteCriteria("parseDouble(pm1.g1.e1, '$#,##0.00') = convert(1234.5, double)", //$NON-NLS-1$
-                                "pm1.g1.e1 = '$1,234.50'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_parseBigDecimal() {
-        helpTestRewriteCriteria("parseBigDecimal(pm1.g1.e1, '#,##0.###') = convert(1234.1234, bigdecimal)", //$NON-NLS-1$
-                                "pm1.g1.e1 = '1,234.123'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_formatDate() {
-        helpTestRewriteCriteria("formatDate(pm3.g1.e2, 'yyyyMMdd') = '20030501'", //$NON-NLS-1$
-                                "pm3.g1.e2 = {d'2003-05-01'}" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_formatTime() {
-        helpTestRewriteCriteria("formatTime(pm3.g1.e3, 'HH mm ss') = '13 25 04'", //$NON-NLS-1$
-                                "pm3.g1.e3 = {t'13:25:04'}" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_formatTimestamp() {
-        helpTestRewriteCriteria("formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss') = '05 01, 1974 - 07:00:00'", //$NON-NLS-1$
-                                "formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss') = '05 01, 1974 - 07:00:00'" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_formatTimestamp1() {
-        helpTestRewriteCriteria("formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss.S') = '05 01, 1974 - 07:00:00.0'", //$NON-NLS-1$
-                                "pm3.g1.e4 = {ts'1974-05-01 07:00:00.0'}" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_formatInteger() {
-        helpTestRewriteCriteria("formatInteger(pm1.g1.e2, '#,##0') = '1,234'", //$NON-NLS-1$
-                                "pm1.g1.e2 = 1234" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_formatInteger1() {
-        helpTestRewriteCriteria("formatInteger(pm1.g1.e2, '#5') = '105'", //$NON-NLS-1$
-                                "formatInteger(pm1.g1.e2, '#5') = '105'" );         //$NON-NLS-1$
-    }
-
-    public void testRewriteCrit_formatLong() {
-        helpTestRewriteCriteria("formatLong(convert(pm1.g1.e2, long), '#,##0') = '1,234,567,890,123'", //$NON-NLS-1$
-                                "convert(pm1.g1.e2, long) = 1234567890123" );         //$NON-NLS-1$
-    }
-    
-    public void testRewriteCrit_formatTimestampInvert() { 
-        String original = "formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss.S') = ?"; //$NON-NLS-1$ 
-        String expected = "pm3.g1.e4 = parseTimestamp(?, 'MM dd, yyyy - HH:mm:ss.S')"; //$NON-NLS-1$ 
-         
-        helpTestRewriteCriteria(original, expected); 
-    } 
-     
-    public void testRewriteCrit_plusInvert() { 
-        String original = "pm1.g1.e2 + 1.1 = ?"; //$NON-NLS-1$ 
-        String expected = "pm1.g1.e2 = ? - 1.1"; //$NON-NLS-1$ 
-         
-        helpTestRewriteCriteria(original, expected);
-    } 
-
-    public void testRewriteCrit_formatBigInteger() {
-        String original = "formatBigInteger(convert(pm1.g1.e2, biginteger), '#,##0') = '1,234,567,890'"; //$NON-NLS-1$
-        String expected = "convert(pm1.g1.e2, biginteger) = 1234567890"; //$NON-NLS-1$
-        
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria origCrit = parseCriteria(original, metadata);
-        Criteria expectedCrit = parseCriteria(expected, metadata);
-        ((CompareCriteria)expectedCrit).setRightExpression(new Constant(new BigInteger("1234567890"))); //$NON-NLS-1$
-        
-        // rewrite
-        try { 
-            Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
-        } catch(QueryValidatorException e) { 
-            e.printStackTrace();
-            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
-        }
-    }
-
-    public void testRewriteCrit_formatFloat() throws Exception {
-        String original = "formatFloat(convert(pm1.g1.e2, float), '#,##0.###') = '1,234.123'"; //$NON-NLS-1$
-        String expected = "convert(pm1.g1.e2, float) = 1234.123"; //$NON-NLS-1$
-        
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria origCrit = parseCriteria(original, metadata);
-        
-        // rewrite
-        Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-        assertEquals("Did not rewrite correctly: ", expected, actual.toString()); //$NON-NLS-1$
-        
-        Function left = (Function)((CompareCriteria)actual).getLeftExpression();
-        
-        assertFalse(left.isImplicit());
-    }
-
-    public void testRewriteCrit_formatDouble() {
-        String original = "formatDouble(convert(pm1.g1.e2, double), '$#,##0.00') = '$1,234.50'"; //$NON-NLS-1$
-        String expected = "convert(pm1.g1.e2, double) = 1234.5"; //$NON-NLS-1$
-        
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria origCrit = parseCriteria(original, metadata);
-        Criteria expectedCrit = parseCriteria(expected, metadata);
-        ((CompareCriteria)expectedCrit).setRightExpression(new Constant(new Double(1234.5)));
-        
-        // rewrite
-        try { 
-            Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
-        } catch(QueryValidatorException e) { 
-            e.printStackTrace();
-            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
-        }
-    }
-
-    public void testRewriteCrit_formatBigDecimal() {
-        String original = "formatBigDecimal(convert(pm1.g1.e2, bigdecimal), '#,##0.###') = convert(1234.5, bigdecimal)"; //$NON-NLS-1$
-        String expected = "convert(pm1.g1.e2, bigdecimal) = 1234.5"; //$NON-NLS-1$
-        
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria origCrit = parseCriteria(original, metadata);
-        Criteria expectedCrit = parseCriteria(expected, metadata);
-        ((CompareCriteria)expectedCrit).setRightExpression(new Constant(new BigDecimal("1234.5"))); //$NON-NLS-1$
-        
-        // rewrite
-        try { 
-            Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
-        } catch(QueryValidatorException e) { 
-            e.printStackTrace();
-            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
-        }
-    }
-    
-    public void testRewriteCritTimestampDiffDate1() {
-        helpTestRewriteCriteria("timestampdiff(SQL_TSI_DAY, {d'2003-05-15'}, {d'2003-05-17'} ) = 2", TRUE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteCritTimestampDiffDate2() {
-        helpTestRewriteCriteria("timestampdiff(SQL_TSI_DAY, {d'2003-06-02'}, {d'2003-05-17'} ) = -16", TRUE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteCritTimestampDiffDate3() {
-        helpTestRewriteCriteria("timestampdiff(SQL_TSI_QUARTER, {d'2002-01-25'}, {d'2003-06-01'} ) = 5", TRUE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteCritTimestampDiffTime1() {
-        helpTestRewriteCriteria("timestampdiff(SQL_TSI_HOUR, {t'03:04:45'}, {t'05:05:36'} ) = 2", TRUE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteCritTimestampDiffTime1_ignorecase() {
-        helpTestRewriteCriteria("timestampdiff(SQL_tsi_HOUR, {t'03:04:45'}, {t'05:05:36'} ) = 2", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteOr1() {
-        helpTestRewriteCriteria("(5 = 5) OR (0 = 1)", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteOr2() {
-        helpTestRewriteCriteria("(0 = 1) OR (5 = 5)", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteOr3() {
-        helpTestRewriteCriteria("(1 = 1) OR (5 = 5)", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteOr4() {
-        helpTestRewriteCriteria("(0 = 1) OR (4 = 5)", FALSE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteOr5() {
-        helpTestRewriteCriteria("(0 = 1) OR (4 = 5) OR (pm1.g1.e1 = 'x')", "(pm1.g1.e1 = 'x')");         //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteOr6() {
-        helpTestRewriteCriteria("(0 = 1) OR (4 = 5) OR (pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')");     //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteOr7() {
-        helpTestRewriteCriteria("(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')");     //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteAnd1() {
-        helpTestRewriteCriteria("(5 = 5) AND (0 = 1)", FALSE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteAnd2() {
-        helpTestRewriteCriteria("(0 = 1) AND (5 = 5)", FALSE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteAnd3() {
-        helpTestRewriteCriteria("(1 = 1) AND (5 = 5)", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteAnd4() {
-        helpTestRewriteCriteria("(0 = 1) AND (4 = 5)", FALSE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteAnd5() { 
-        helpTestRewriteCriteria("(1 = 1) AND (5 = 5) AND (pm1.g1.e1 = 'x')", "(pm1.g1.e1 = 'x')");             //$NON-NLS-1$ //$NON-NLS-2$
-    }
- 
-    public void testRewriteAnd6() { 
-        helpTestRewriteCriteria("(1 = 1) AND (5 = 5) AND (pm1.g1.e1 = 'x') and (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')");             //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteAnd7() {
-        helpTestRewriteCriteria("(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')");     //$NON-NLS-1$ //$NON-NLS-2$
-    }
-        
-    public void testRewriteMixed1() {
-        helpTestRewriteCriteria("((1=1) AND (1=1)) OR ((1=1) AND (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed2() {
-        helpTestRewriteCriteria("((1=2) AND (1=1)) OR ((1=1) AND (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed3() {
-        helpTestRewriteCriteria("((1=1) AND (1=2)) OR ((1=1) AND (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed4() {
-        helpTestRewriteCriteria("((1=1) AND (1=1)) OR ((1=2) AND (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed5() {
-        helpTestRewriteCriteria("((1=1) AND (1=1)) OR ((1=1) AND (1=2))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed6() {
-        helpTestRewriteCriteria("((1=2) AND (1=1)) OR ((1=2) AND (1=1))", FALSE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed7() {
-        helpTestRewriteCriteria("((1=1) AND (1=2)) OR ((1=1) AND (1=2))", FALSE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed8() {
-        helpTestRewriteCriteria("((1=2) AND (1=2)) OR ((1=2) AND (1=2))", FALSE_STR); //$NON-NLS-1$
-    }
-    
-    public void testRewriteMixed9() {
-        helpTestRewriteCriteria("((1=1) OR (1=1)) AND ((1=1) OR (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed10() {
-        helpTestRewriteCriteria("((1=2) OR (1=1)) AND ((1=1) OR (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed11() {
-        helpTestRewriteCriteria("((1=1) OR (1=2)) AND ((1=1) OR (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed12() {
-        helpTestRewriteCriteria("((1=1) OR (1=1)) AND ((1=2) OR (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed13() {
-        helpTestRewriteCriteria("((1=1) OR (1=1)) AND ((1=1) OR (1=2))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed14() {
-        helpTestRewriteCriteria("((1=2) OR (1=1)) AND ((1=2) OR (1=1))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed15() {
-        helpTestRewriteCriteria("((1=1) OR (1=2)) AND ((1=1) OR (1=2))", TRUE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteMixed16() {
-        helpTestRewriteCriteria("((1=2) OR (1=2)) AND ((1=2) OR (1=2))", FALSE_STR); //$NON-NLS-1$
-    }
-
-    public void testRewriteNot1() {
-        helpTestRewriteCriteria("NOT (1=1)", FALSE_STR);     //$NON-NLS-1$
-    }   
-
-    public void testRewriteNot2() {
-        helpTestRewriteCriteria("NOT (1=2)", TRUE_STR);     //$NON-NLS-1$
-    }   
-    
-    public void testRewriteNot3() {
-        helpTestRewriteCriteria("NOT (pm1.g1.e1='x')", "NOT (pm1.g1.e1 = 'x')");     //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteDefect1() {
-        helpTestRewriteCriteria("(('DE' = 'LN') AND (null > '2002-01-01')) OR (('DE' = 'DE') AND (pm1.g1.e1 > '9000000'))", "(pm1.g1.e1 > '9000000')");         //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteQueryCriteriaAlwaysTrue() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE 0 = 0", //$NON-NLS-1$
-                                "SELECT e1 FROM pm1.g1"); //$NON-NLS-1$
-    }
-    
-    public void testSubquery1() {
-        helpTestRewriteCommand("SELECT e1 FROM (SELECT e1 FROM pm1.g1 WHERE (1 - 1) = (0 + 0)) AS x", //$NON-NLS-1$
-                                "SELECT e1 FROM (SELECT e1 FROM pm1.g1) AS x"); //$NON-NLS-1$
-    }
-
-    public void testExistsSubquery() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
-                                "SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
-    }
-
-    public void testCompareSubqueryANY() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE '3' = ANY (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
-                                "SELECT e1 FROM pm1.g1 WHERE '3' = SOME (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
-    }
-
-    public void testCompareSubquery() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE '3' = SOME (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
-                                "SELECT e1 FROM pm1.g1 WHERE '3' = SOME (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
-    }
-    
-    public void testCompareSubqueryUnknown() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE null = SOME (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
-                                "SELECT e1 FROM pm1.g1 WHERE null <> null"); //$NON-NLS-1$
-    }
-
-    public void testINClauseSubquery() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE '3' IN (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
-                                "SELECT e1 FROM pm1.g1 WHERE '3' IN (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
-    }
-
-    public void testRewriteXMLCriteria1() {
-        helpTestRewriteCriteria("context(pm1.g1.e1, pm1.g1.e1) = convert(5, string)", "context(pm1.g1.e1, pm1.g1.e1) = '5'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteXMLCriteria2() {
-        helpTestRewriteCriteria("context(pm1.g1.e1, convert(5, string)) = 2+3", "context(pm1.g1.e1, '5') = '5'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    // HAS Criteria
-    public void testRewriteProcedure1() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-				
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    // HAS Criteria
-    public void testRewriteProcedure2() {
-    	
-		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n";		 //$NON-NLS-1$
-		procedure = procedure + "ELSE \n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n";		 //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-				
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    // HAS Criteria
-    public void testRewriteProcedure3() {
-    	
-		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n";		 //$NON-NLS-1$
-		procedure = procedure + "ELSE \n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n";		 //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-				
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    public void testRewriteProcedure4() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (INPUT.e2 = 1)\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-				
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }    
-    
-    // CHANGING
-    public void testRewriteProcedure5() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (CHANGING.e1 = \"false\")\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e2);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    // CHANGING
-    public void testRewriteProcedure6() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (CHANGING.e1 = \"true\")\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }     
-    
-    // TRANSLATE CRITERIA
-    public void testRewriteProcedure7() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (CHANGING.e1 = \"true\")\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select e2 from pm1.g1 where TRANSLATE = CRITERIA ON (vm1.g1.e2);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT e2 FROM pm1.g1 WHERE pm1.g1.e2 = 10;\n";				 //$NON-NLS-1$
-		rewritProc = rewritProc + "END";		 //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    // TRANSLATE CRITERIA
-    public void testRewriteProcedure8() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (CHANGING.e1 = \"true\")\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select e2 from pm1.g1 where TRANSLATE = CRITERIA ON (vm1.g1.e2) with (vm1.g1.e2 = convert(sqrt(pm1.g1.e2), integer));\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT e2 FROM pm1.g1 WHERE convert(sqrt(pm1.g1.e2), integer) = 10;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    // rewrite input/ changing variables
-    public void testRewriteProcedure9() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "Declare String var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "if(var1 = 'x' or var1 = 'y')\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n";         //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2, Input.e2, CHANGING.e2, CHANGING.e1 from pm1.g1 order by CHANGING.e1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (e1) values('x')"; //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE String var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "IF((var1 = 'x') OR (var1 = 'y'))\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2, null AS E2_0, FALSE AS E2_1, TRUE AS E1 FROM pm1.g1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-    public void testRewriteProcedure10() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1, pm1.g2 where TRANSLATE = CRITERIA ON (e2) WITH (e2 = pm1.g1.e2 + 20);\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g1 SET e1='x' where e2 = e2 + 50"; //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1, pm1.g2 WHERE (pm1.g1.e2 + 20) = ((pm1.g1.e2 + 20) + 50);\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-	// virtual group elements used in procedure in if statement(HAS CRITERIA)
-    public void testRewriteProcedure11() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE string var1;\n"; //$NON-NLS-1$
-		procedure = procedure + "var1 = INPUT.e1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g1 SET e1=40";     //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE string var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "var1 = '40';\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-	// with complex query transform
-    public void testRewriteProcedure12() {
-        String procedure = "CREATE PROCEDURE  "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (x = CONCAT(e1 , 'z'));\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g3 SET x='x' where x =CONCAT(x , 'y')"; //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE CONCAT(e1, 'z') = CONCAT(CONCAT(e1, 'z'), 'y');\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-	// with complex query transform
-    public void testRewriteProcedure13() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (x = CONCAT(e1 , 'z'), y = convert(CONCAT(e1 , 'k'), integer));\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g3 SET x='x' where x =CONCAT(x , 'y') and y= 1"; //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE (CONCAT(e1, 'z') = CONCAT(CONCAT(e1, 'z'), 'y')) AND (convert(CONCAT(e1, 'k'), integer) = 1);\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-    public void testRewriteProcedure14() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (e4 = sqrt(e4));\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g3 SET x='x' where e4= 1"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE sqrt(e4) = 1.0;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-    public void testRewriteProcedure15() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (e4 = e4/50);\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g3 SET x='x' where y= 1"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE e2 = 0;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-    public void testRewriteProcedure16() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE CRITERIA;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g3 SET x='x' where e4= 1"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE e4 = 0.02;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-    public void testRewriteProcedure17() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE LIKE CRITERIA WITH (e4 = e4/50);\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n";         //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g3 SET x='x' where e4= 1"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// Bug 8212 elements in INPUT and CHANGING special groups are cese sensitive
-    public void testRewriteProcedure18() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "Select Input.E1, Input.e2, CHANGING.e2, CHANGING.E1 from pm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (e1, E2) values('x', 1)"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT 'x', 1, TRUE, TRUE FROM pm1.g1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// elements being set in updates are dropped if INPUT var is not available, unless a default is available
-    // Note that this test is a little odd in that it is an update inside of an insert
-    public void testRewriteProcedure19() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "update pm1.g1 set e1=Input.E1, e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (E2) values(1)"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "UPDATE pm1.g1 SET e1 = 'xyz', e2 = 1, e3 = TRUE;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// elements being set in updates are dropped if INPUT var is not available, unless a default is supplied
-    
-    //this test fails because the default for E1 'xyz' cannot be converted into a integer
-    public void testRewriteProcedure21() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "update pm1.g1 set e1=convert(Input.E1, integer)+INPUT.E2, e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (E3) values({b'true'})"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "UPDATE pm1.g1 SET e3 = TRUE;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		this.helpFailUpdateProcedure(procedure, userQuery, FakeMetadataObject.Props.INSERT_PROCEDURE);
-	}
-    
-    public void testRewriteProcedure21a() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "update pm1.g1 set e1=convert(Input.E1, integer)+INPUT.E2, e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (E1) values(1)"; //$NON-NLS-1$
-
-        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "UPDATE pm1.g1 SET e1 = null, e2 = null, e3 = TRUE;\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-                                                        FakeMetadataObject.Props.INSERT_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-
-	
-	// none of input variables on update statement changing
-    public void testRewriteProcedure22() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "update pm1.g1 set e1=convert(Input.E1, integer)+INPUT.E2, e2=Input.e2;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "update vm1.g1 set E3 = {b'true'}"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// none of input variables on update statement changing
-    public void testRewriteProcedure23() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "update pm1.g1 set e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "update vm1.g1 set E1 = 'x'"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-    
-    //with an insert, defaults are used
-    public void testRewriteProcedure23a() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "update pm1.g1 set e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (E1) values('x')"; //$NON-NLS-1$
-
-        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "UPDATE pm1.g1 SET e2 = null, e3 = TRUE;\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-                FakeMetadataObject.Props.INSERT_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-	// elements being set in updates are dropped if INPUT var is not available
-    public void testRewriteProcedure24() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "UPDATE pm1.g1 SET e2=Input.e2 WHERE TRANSLATE LIKE CRITERIA ON (e1) WITH (e1=concat(pm1.g1.e1, \"%\"));\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g1 set E2=1 where e2 = 1 and e1 LIKE 'mnopxyz_'"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "UPDATE pm1.g1 SET e2 = 1 WHERE concat(pm1.g1.e1, '%') LIKE 'mnopxyz_';\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-
-	// INPUT vars in insert statements replaced by default variable when user's inser ignores values
-    public void testRewriteProcedure25() {
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "INSERT into pm1.g1 (e1,e2,e3,e4) values (Input.e1, Input.e2, Input.e3, Input.e4);"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "INSERT into vm1.g1 (E2) values (1)"; //$NON-NLS-1$
-
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "INSERT INTO pm1.g1 (e1, e2, e3, e4) VALUES ('xyz', 1, TRUE, 123.456);\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.INSERT_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-	public void testRewriteProcedure26() {
-		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		procedure = procedure + "Select pm1.g1.e2 from pm1.g1, pm1.g2 where TRANSLATE = CRITERIA ON (e2);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n";         //$NON-NLS-1$
-
-		String userQuery = "UPDATE vm1.g1 SET e1='x' where e2 = e2 + 50"; //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1, pm1.g2 WHERE pm1.g1.e2 = (pm1.g1.e2 + 50);\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-		assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-	
-	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
-	public void testRewriteProcedure27() {
-		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		procedure = procedure + "Select pm1.g1.e2 from pm1.g1, pm1.g2 where TRANSLATE = CRITERIA ON (e2);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n";         //$NON-NLS-1$
-
-		String userQuery = "UPDATE vm1.g1 SET e1='x' where e2 LIKE 'xyz'"; //$NON-NLS-1$
-        
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1, pm1.g2 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-		assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-	}
-
-    /**
-     * Per defect 9380 - 
-     * A criteria of the form  
-     * (? + 1) < (null)  
-     * caused a problem in the QueryRewriter.simplifyMathematicalCriteria method.
-     * At the beginning of the method, the null constant is rewritten so that it
-     * loses it's implicit type conversion to integer, then later on a function
-     * descriptor couldn't be found for the "minus" operation for the two types 
-     * integer and MetaMatrix's null type.
-     */
-    public void testRewriteProcedure_9380() {
-        
-        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure = procedure + "DECLARE integer var2;\n"; //$NON-NLS-1$
-        procedure = procedure + "if((var1 + 1) < length(input.e1))\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n";         //$NON-NLS-1$
-        procedure = procedure + "var2 = INPUT.e2;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userQuery = "UPDATE vm1.g1 SET e2=30";     //$NON-NLS-1$
-        
-        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "BEGIN\n";         //$NON-NLS-1$
-        rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "DECLARE integer var2;\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "END"; //$NON-NLS-1$
-
-        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-                FakeMetadataObject.Props.UPDATE_PROCEDURE);
-
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    //base test.  no change is expected
-    public void testRewriteLookupFunction1() {
-        String criteria = "lookup('pm1.g1','e1', 'e2', 'value') = 'ab'"; //$NON-NLS-1$
-        CompareCriteria expected = (CompareCriteria)parseCriteria(criteria, FakeMetadataFactory.example1Cached()); 
-        helpTestRewriteCriteria(criteria, expected, FakeMetadataFactory.example1Cached());
-    }
-    
-    public void testRewriteLookupFunction1b() {
-        helpTestRewriteCriteria("lookup('pm1.g1','e1', 'e2', pm1.g1.e1) = 'ab'", "lookup('pm1.g1','e1', 'e2', pm1.g1.e1) = 'ab'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /** defect 11630 1 should still get rewritten as '1'*/
-    public void testRewriteLookupFunctionCompoundCriteria() {
-        String criteria = "LOOKUP('pm1.g1','e1', 'e2', 'value') IS NULL AND pm1.g1.e1='1'"; //$NON-NLS-1$
-        CompoundCriteria expected = (CompoundCriteria)parseCriteria(criteria, FakeMetadataFactory.example1Cached()); 
-        helpTestRewriteCriteria("LOOKUP('pm1.g1','e1', 'e2', 'value') IS NULL AND pm1.g1.e1=1", expected, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$ 
-    }
-
-    public void testSelectWithNoFrom() {
-        helpTestRewriteCommand("SELECT 5", "SELECT 5"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    //defect 9822
-    public void testStoredProcedure_9822() throws Exception {
-
-        QueryParser parser = new QueryParser();
-        Command command = parser.parseCommand("exec pm1.sp4(5)");             //$NON-NLS-1$
-        
-        // resolve
-        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
-        
-        // rewrite
-        Command rewriteCommand = QueryRewriter.rewrite(command, null, null, null);
-        
-        List parameters = ((StoredProcedure)rewriteCommand).getParameters();
-        
-        Iterator iter = parameters.iterator();
-        while(iter.hasNext()){
-            SPParameter param = (SPParameter)iter.next();
-            if(param.getParameterType() == ParameterInfo.IN || param.getParameterType() == ParameterInfo.INOUT){
-                assertTrue(param.getExpression() instanceof Constant);
-            }
-        }  
-    }
-    
-    public void testRewriteRecursive() {
-        Command c = helpTestRewriteCommand("SELECT e2 FROM vm1.g33", "SELECT e2 FROM vm1.g33"); //$NON-NLS-1$ //$NON-NLS-2$
-        Command innerCommand = (Command) c.getSubCommands().get(0);
-        
-        assertEquals("Inner command not rewritten", "SELECT e2 FROM pm1.g1 WHERE e2 = 2", innerCommand.toString()); //$NON-NLS-1$ //$NON-NLS-2$
-        
-    }
-    
-    public void testRewriteFunctionThrowsEvaluationError() {
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria origCrit = parseCriteria("5 / 0 = 5", metadata); //$NON-NLS-1$
-        
-        // rewrite
-        try { 
-            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            fail("Expected QueryValidatorException due to divide by 0"); //$NON-NLS-1$
-        } catch(QueryValidatorException e) {
-            assertEquals("Unable to evaluate (5 / 0): Error while evaluating function /", e.getMessage());  //$NON-NLS-1$
-        }       
-    }
-    
-    public void testRewriteConvertThrowsEvaluationError() {
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-        Criteria origCrit = parseCriteria("convert('x', integer) = 0", metadata); //$NON-NLS-1$
-        
-        // rewrite
-        try { 
-            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
-            fail("Expected QueryValidatorException due to invalid string"); //$NON-NLS-1$
-        } catch(QueryValidatorException e) {
-            assertEquals("Unable to convert 'x' of type [string] to the expected type [integer].", e.getMessage()); //$NON-NLS-1$
-        }       
-    }
-    
-    public void testDefect13458() {
-    	
-		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
-		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
-		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		procedure = procedure + "END\n"; //$NON-NLS-1$
-		
-		String userQuery = "delete from vm1.g1 where e1='1'"; //$NON-NLS-1$
-		
-		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
-		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1;\n"; //$NON-NLS-1$
-		rewritProc = rewritProc + "END"; //$NON-NLS-1$
-		
-		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-				FakeMetadataObject.Props.DELETE_PROCEDURE);				
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    public void testRewriteCase1954() {
-        helpTestRewriteCriteria("convert(pm1.g1.e2, string) = '3'", "pm1.g1.e2 = 3"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCase1954a() {
-        helpTestRewriteCriteria("cast(pm1.g1.e2 as string) = '3'", "pm1.g1.e2 = 3"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCase1954b() throws Exception{
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
-
-        // Have to hand-build the criteria, because 3.0 gets parsed as a Float by default
-        // pm1.g1.e4 = 3.0
-        CompareCriteria expected = new CompareCriteria();
-        ElementSymbol leftElement = new ElementSymbol("pm1.g1.e4"); //$NON-NLS-1$
-        Constant constant = new Constant(new Double(3.0), DataTypeManager.DefaultDataClasses.DOUBLE);
-        expected.setLeftExpression(leftElement);
-        expected.setRightExpression(constant);
-        // resolve against metadata
-        QueryResolver.resolveCriteria(expected, metadata);
-        
-        helpTestRewriteCriteria("convert(pm1.g1.e4, string) = '3'", expected, metadata); //$NON-NLS-1$ 
-    }    
-
-    public void testRewriteCase1954c() {
-        helpTestRewriteCriteria("convert(pm1.g1.e1, string) = 'x'", "pm1.g1.e1 = 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }    
-
-    /** Test some other type besides 'string' has no effect */
-    public void testRewriteCase1954d() {
-        helpTestRewriteCriteria("convert(pm1.g1.e1, timestamp) = {ts '2005-01-03 00:00:00.0'}", "convert(pm1.g1.e1, timestamp) = {ts '2005-01-03 00:00:00.0'}"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /** Test some other type besides 'string' has no effect */
-    public void testRewriteCase1954e() {
-        helpTestRewriteCriteria("convert(pm1.g1.e4, integer) = 2", "convert(pm1.g1.e4, integer) = 2"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /** Check that this fails, x is not convertable to an int */
-    public void testRewriteCase1954f() {
-        helpTestRewriteCriteria("convert(pm1.g1.e2, string) = 'x'", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    /** Check that this returns true, x is not convertable to an int */
-    public void testRewriteCase1954f1() {
-        helpTestRewriteCriteria("convert(pm1.g1.e2, string) != 'x'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCase1954Set() {
-        helpTestRewriteCriteria("convert(pm1.g1.e2, string) in ('2', '3')", "pm1.g1.e2 IN (2,3)"); //$NON-NLS-1$ //$NON-NLS-2$
-    }    
-
-    public void testRewriteCase1954SetA() {
-        helpTestRewriteCriteria("convert(pm1.g1.e2, string) in ('2', 'x')", "convert(pm1.g1.e2, string) in ('2', 'x')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }    
-    
-    public void testRewriteCase1954SetB() {
-        helpTestRewriteCriteria("cast(pm1.g1.e2 as string) in ('2', '3')", "pm1.g1.e2 IN (2,3)"); //$NON-NLS-1$ //$NON-NLS-2$
-    }    
-    
-    public void testRewriteCase1954SetC() {
-        helpTestRewriteCriteria("concat(pm1.g1.e2, 'string') in ('2', '3')", "concat(pm1.g1.e2, 'string') in ('2', '3')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }    
-
-    public void testRewriteCase1954SetD() {
-        helpTestRewriteCriteria("convert(pm1.g1.e2, string) in ('2', pm1.g1.e1)", "convert(pm1.g1.e2, string) in ('2', pm1.g1.e1)"); //$NON-NLS-1$ //$NON-NLS-2$
-    }      
-    
-    // First WHEN always true, so rewrite as THEN expression
-    public void testRewriteCaseExpr1() {
-        helpTestRewriteCriteria("case when 0=0 then 1 else 2 end = 1", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    // First WHEN always false, so rewrite as ELSE expression
-    public void testRewriteCaseExpr2() {
-        helpTestRewriteCriteria("case when 0=1 then 1 else 2 end = 1", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    // First WHEN can't be rewritten, so no changes
-    public void testRewriteCaseExpr3() {
-        helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then 1 else 2 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 1 ELSE 2 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCaseExpr4() {
-        helpTestRewriteCriteria("lookup('pm1.g1', 'e2', 'e1', case when 1=1 then pm1.g1.e1 end) = 0", "lookup('pm1.g1', 'e2', 'e1', pm1.g1.e1) = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    // First WHEN always false, so remove it
-    public void testRewriteCaseExpr5() {
-        helpTestRewriteCriteria("case when 0=1 then 1 when 0 = pm1.g1.e2 then 2 else 3 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 2 ELSE 3 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCaseExprForCase5413aFrom502() {
-        helpTestRewriteCriteria("pm1.g2.e1 = case when 0 = pm1.g1.e2 then 2 else 2 end", "pm1.g2.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCaseExprForCase5413bFrom502() {
-        helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then null else null end IS NULL", TRUE_STR); //$NON-NLS-1$ 
-    }
-    
-    
-    public void testRewriteCaseExprForCase5413a() {
-        helpTestRewriteCriteria("pm1.g2.e1 = case when 0 = pm1.g1.e2 then 2 else 2 end", "pm1.g2.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteCaseExprForCase5413b() {
-        helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then null else null end IS NULL", TRUE_STR); //$NON-NLS-1$ 
-    }
-
-    // First WHEN always true, so rewrite as THEN expression
-    public void testRewriteSearchedCaseExpr1() {
-        helpTestRewriteCriteria("case 0 when 0 then 1 else 2 end = 1", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    // First WHEN always false, so rewrite as ELSE expression
-    public void testRewriteSearchedCaseExpr2() {
-        helpTestRewriteCriteria("case 0 when 1 then 1 else 2 end = 1", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteSearchedCaseExpr3() {
-        helpTestRewriteCriteria("case 0 when pm1.g1.e2 then 1 else 2 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 1 ELSE 2 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteSearchedCaseExpr4() {
-        String criteria = "lookup('pm1.g1', 'e2', 'e1', null) = 0"; //$NON-NLS-1$
-        CompareCriteria expected = (CompareCriteria)parseCriteria(criteria, FakeMetadataFactory.example1Cached()); 
-        helpTestRewriteCriteria("lookup('pm1.g1', 'e2', 'e1', case 0 when 1 then pm1.g1.e1 end) = 0", expected, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$
-    }
-
-    // First WHEN always false, so remove it
-    public void testRewriteSearchedCaseExpr5() {
-        helpTestRewriteCriteria("case 0 when 1 then 1 when pm1.g1.e2 then 2 else 3 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 2 ELSE 3 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testDefect16879_1(){
-    	helpTestRewriteCommand("SELECT decodestring(e1, 'a, b') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testDefect16879_2(){
-    	helpTestRewriteCommand("SELECT decodestring(e1, 'a, b, c, d') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 = 'c' THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testDefect16879_3(){
-    	helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testDefect16879_4(){
-    	helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b, c, d') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 = 'c' THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testDefect16879_5(){
-        helpTestRewriteCommand("SELECT decodeinteger(e1, 'null, b, c, d') FROM pm1.g1", "SELECT CASE WHEN e1 IS NULL THEN 'b' WHEN e1 = 'c' THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testDefect16879_6(){
-        helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b, null, d') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 IS NULL THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testDefect16879_7(){
-        helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b, null, d, e') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 IS NULL THEN 'd' ELSE 'e' END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
+    }
+
+    public void testRewriteCrit_parseInteger() {
+        helpTestRewriteCriteria("parseInteger(pm1.g1.e1, '#,##0') = 1234", //$NON-NLS-1$
+                                "pm1.g1.e1 = '1,234'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseLong() {
+        helpTestRewriteCriteria("parseLong(pm1.g1.e1, '#,##0') = convert(1234, long)", //$NON-NLS-1$
+                                "pm1.g1.e1 = '1,234'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseBigInteger() {
+        helpTestRewriteCriteria("parseBigInteger(pm1.g1.e1, '#,##0') = convert(1234, biginteger)", //$NON-NLS-1$
+                                "pm1.g1.e1 = '1,234'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseFloat() {
+        helpTestRewriteCriteria("parseFloat(pm1.g1.e1, '#,##0.###') = convert(1234.1234, float)", //$NON-NLS-1$
+                                "pm1.g1.e1 = '1,234.123'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseDouble() {
+        helpTestRewriteCriteria("parseDouble(pm1.g1.e1, '$#,##0.00') = convert(1234.5, double)", //$NON-NLS-1$
+                                "pm1.g1.e1 = '$1,234.50'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_parseBigDecimal() {
+        helpTestRewriteCriteria("parseBigDecimal(pm1.g1.e1, '#,##0.###') = convert(1234.1234, bigdecimal)", //$NON-NLS-1$
+                                "pm1.g1.e1 = '1,234.123'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_formatDate() {
+        helpTestRewriteCriteria("formatDate(pm3.g1.e2, 'yyyyMMdd') = '20030501'", //$NON-NLS-1$
+                                "pm3.g1.e2 = {d'2003-05-01'}" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_formatTime() {
+        helpTestRewriteCriteria("formatTime(pm3.g1.e3, 'HH mm ss') = '13 25 04'", //$NON-NLS-1$
+                                "pm3.g1.e3 = {t'13:25:04'}" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_formatTimestamp() {
+        helpTestRewriteCriteria("formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss') = '05 01, 1974 - 07:00:00'", //$NON-NLS-1$
+                                "formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss') = '05 01, 1974 - 07:00:00'" );         //$NON-NLS-1$
+    }
     
+    public void testRewriteCrit_formatTimestamp1() {
+        helpTestRewriteCriteria("formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss.S') = '05 01, 1974 - 07:00:00.0'", //$NON-NLS-1$
+                                "pm3.g1.e4 = {ts'1974-05-01 07:00:00.0'}" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_formatInteger() {
+        helpTestRewriteCriteria("formatInteger(pm1.g1.e2, '#,##0') = '1,234'", //$NON-NLS-1$
+                                "pm1.g1.e2 = 1234" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_formatInteger1() {
+        helpTestRewriteCriteria("formatInteger(pm1.g1.e2, '#5') = '105'", //$NON-NLS-1$
+                                "formatInteger(pm1.g1.e2, '#5') = '105'" );         //$NON-NLS-1$
+    }
+
+    public void testRewriteCrit_formatLong() {
+        helpTestRewriteCriteria("formatLong(convert(pm1.g1.e2, long), '#,##0') = '1,234,567,890,123'", //$NON-NLS-1$
+                                "convert(pm1.g1.e2, long) = 1234567890123" );         //$NON-NLS-1$
+    }
+    
+    public void testRewriteCrit_formatTimestampInvert() { 
+        String original = "formatTimestamp(pm3.g1.e4, 'MM dd, yyyy - HH:mm:ss.S') = ?"; //$NON-NLS-1$ 
+        String expected = "pm3.g1.e4 = parseTimestamp(?, 'MM dd, yyyy - HH:mm:ss.S')"; //$NON-NLS-1$ 
+         
+        helpTestRewriteCriteria(original, expected); 
+    } 
+     
+    public void testRewriteCrit_plusInvert() { 
+        String original = "pm1.g1.e2 + 1.1 = ?"; //$NON-NLS-1$ 
+        String expected = "pm1.g1.e2 = ? - 1.1"; //$NON-NLS-1$ 
+         
+        helpTestRewriteCriteria(original, expected);
+    } 
+
+    public void testRewriteCrit_formatBigInteger() {
+        String original = "formatBigInteger(convert(pm1.g1.e2, biginteger), '#,##0') = '1,234,567,890'"; //$NON-NLS-1$
+        String expected = "convert(pm1.g1.e2, biginteger) = 1234567890"; //$NON-NLS-1$
+        
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria origCrit = parseCriteria(original, metadata);
+        Criteria expectedCrit = parseCriteria(expected, metadata);
+        ((CompareCriteria)expectedCrit).setRightExpression(new Constant(new BigInteger("1234567890"))); //$NON-NLS-1$
+        
+        // rewrite
+        try { 
+            Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
+        } catch(QueryValidatorException e) { 
+            e.printStackTrace();
+            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    public void testRewriteCrit_formatFloat() throws Exception {
+        String original = "formatFloat(convert(pm1.g1.e2, float), '#,##0.###') = '1,234.123'"; //$NON-NLS-1$
+        String expected = "convert(pm1.g1.e2, float) = 1234.123"; //$NON-NLS-1$
+        
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria origCrit = parseCriteria(original, metadata);
+        
+        // rewrite
+        Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+        assertEquals("Did not rewrite correctly: ", expected, actual.toString()); //$NON-NLS-1$
+        
+        Function left = (Function)((CompareCriteria)actual).getLeftExpression();
+        
+        assertFalse(left.isImplicit());
+    }
+
+    public void testRewriteCrit_formatDouble() {
+        String original = "formatDouble(convert(pm1.g1.e2, double), '$#,##0.00') = '$1,234.50'"; //$NON-NLS-1$
+        String expected = "convert(pm1.g1.e2, double) = 1234.5"; //$NON-NLS-1$
+        
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria origCrit = parseCriteria(original, metadata);
+        Criteria expectedCrit = parseCriteria(expected, metadata);
+        ((CompareCriteria)expectedCrit).setRightExpression(new Constant(new Double(1234.5)));
+        
+        // rewrite
+        try { 
+            Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
+        } catch(QueryValidatorException e) { 
+            e.printStackTrace();
+            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    public void testRewriteCrit_formatBigDecimal() {
+        String original = "formatBigDecimal(convert(pm1.g1.e2, bigdecimal), '#,##0.###') = convert(1234.5, bigdecimal)"; //$NON-NLS-1$
+        String expected = "convert(pm1.g1.e2, bigdecimal) = 1234.5"; //$NON-NLS-1$
+        
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria origCrit = parseCriteria(original, metadata);
+        Criteria expectedCrit = parseCriteria(expected, metadata);
+        ((CompareCriteria)expectedCrit).setRightExpression(new Constant(new BigDecimal("1234.5"))); //$NON-NLS-1$
+        
+        // rewrite
+        try { 
+            Criteria actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
+        } catch(QueryValidatorException e) { 
+            e.printStackTrace();
+            fail("Exception during rewriting (" + e.getClass().getName() + "): " + e.getMessage());     //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+    
+    public void testRewriteCritTimestampDiffDate1() {
+        helpTestRewriteCriteria("timestampdiff(SQL_TSI_DAY, {d'2003-05-15'}, {d'2003-05-17'} ) = 2", TRUE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteCritTimestampDiffDate2() {
+        helpTestRewriteCriteria("timestampdiff(SQL_TSI_DAY, {d'2003-06-02'}, {d'2003-05-17'} ) = -16", TRUE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteCritTimestampDiffDate3() {
+        helpTestRewriteCriteria("timestampdiff(SQL_TSI_QUARTER, {d'2002-01-25'}, {d'2003-06-01'} ) = 5", TRUE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteCritTimestampDiffTime1() {
+        helpTestRewriteCriteria("timestampdiff(SQL_TSI_HOUR, {t'03:04:45'}, {t'05:05:36'} ) = 2", TRUE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteCritTimestampDiffTime1_ignorecase() {
+        helpTestRewriteCriteria("timestampdiff(SQL_tsi_HOUR, {t'03:04:45'}, {t'05:05:36'} ) = 2", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteOr1() {
+        helpTestRewriteCriteria("(5 = 5) OR (0 = 1)", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteOr2() {
+        helpTestRewriteCriteria("(0 = 1) OR (5 = 5)", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteOr3() {
+        helpTestRewriteCriteria("(1 = 1) OR (5 = 5)", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteOr4() {
+        helpTestRewriteCriteria("(0 = 1) OR (4 = 5)", FALSE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteOr5() {
+        helpTestRewriteCriteria("(0 = 1) OR (4 = 5) OR (pm1.g1.e1 = 'x')", "(pm1.g1.e1 = 'x')");         //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteOr6() {
+        helpTestRewriteCriteria("(0 = 1) OR (4 = 5) OR (pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')");     //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteOr7() {
+        helpTestRewriteCriteria("(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')");     //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteAnd1() {
+        helpTestRewriteCriteria("(5 = 5) AND (0 = 1)", FALSE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteAnd2() {
+        helpTestRewriteCriteria("(0 = 1) AND (5 = 5)", FALSE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteAnd3() {
+        helpTestRewriteCriteria("(1 = 1) AND (5 = 5)", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteAnd4() {
+        helpTestRewriteCriteria("(0 = 1) AND (4 = 5)", FALSE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteAnd5() { 
+        helpTestRewriteCriteria("(1 = 1) AND (5 = 5) AND (pm1.g1.e1 = 'x')", "(pm1.g1.e1 = 'x')");             //$NON-NLS-1$ //$NON-NLS-2$
+    }
+ 
+    public void testRewriteAnd6() { 
+        helpTestRewriteCriteria("(1 = 1) AND (5 = 5) AND (pm1.g1.e1 = 'x') and (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')");             //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteAnd7() {
+        helpTestRewriteCriteria("(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')");     //$NON-NLS-1$ //$NON-NLS-2$
+    }
+        
+    public void testRewriteMixed1() {
+        helpTestRewriteCriteria("((1=1) AND (1=1)) OR ((1=1) AND (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed2() {
+        helpTestRewriteCriteria("((1=2) AND (1=1)) OR ((1=1) AND (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed3() {
+        helpTestRewriteCriteria("((1=1) AND (1=2)) OR ((1=1) AND (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed4() {
+        helpTestRewriteCriteria("((1=1) AND (1=1)) OR ((1=2) AND (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed5() {
+        helpTestRewriteCriteria("((1=1) AND (1=1)) OR ((1=1) AND (1=2))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed6() {
+        helpTestRewriteCriteria("((1=2) AND (1=1)) OR ((1=2) AND (1=1))", FALSE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed7() {
+        helpTestRewriteCriteria("((1=1) AND (1=2)) OR ((1=1) AND (1=2))", FALSE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed8() {
+        helpTestRewriteCriteria("((1=2) AND (1=2)) OR ((1=2) AND (1=2))", FALSE_STR); //$NON-NLS-1$
+    }
+    
+    public void testRewriteMixed9() {
+        helpTestRewriteCriteria("((1=1) OR (1=1)) AND ((1=1) OR (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed10() {
+        helpTestRewriteCriteria("((1=2) OR (1=1)) AND ((1=1) OR (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed11() {
+        helpTestRewriteCriteria("((1=1) OR (1=2)) AND ((1=1) OR (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed12() {
+        helpTestRewriteCriteria("((1=1) OR (1=1)) AND ((1=2) OR (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed13() {
+        helpTestRewriteCriteria("((1=1) OR (1=1)) AND ((1=1) OR (1=2))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed14() {
+        helpTestRewriteCriteria("((1=2) OR (1=1)) AND ((1=2) OR (1=1))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed15() {
+        helpTestRewriteCriteria("((1=1) OR (1=2)) AND ((1=1) OR (1=2))", TRUE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteMixed16() {
+        helpTestRewriteCriteria("((1=2) OR (1=2)) AND ((1=2) OR (1=2))", FALSE_STR); //$NON-NLS-1$
+    }
+
+    public void testRewriteNot1() {
+        helpTestRewriteCriteria("NOT (1=1)", FALSE_STR);     //$NON-NLS-1$
+    }   
+
+    public void testRewriteNot2() {
+        helpTestRewriteCriteria("NOT (1=2)", TRUE_STR);     //$NON-NLS-1$
+    }   
+    
+    public void testRewriteNot3() {
+        helpTestRewriteCriteria("NOT (pm1.g1.e1='x')", "NOT (pm1.g1.e1 = 'x')");     //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteDefect1() {
+        helpTestRewriteCriteria("(('DE' = 'LN') AND (null > '2002-01-01')) OR (('DE' = 'DE') AND (pm1.g1.e1 > '9000000'))", "(pm1.g1.e1 > '9000000')");         //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteQueryCriteriaAlwaysTrue() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE 0 = 0", //$NON-NLS-1$
+                                "SELECT e1 FROM pm1.g1"); //$NON-NLS-1$
+    }
+    
+    public void testSubquery1() {
+        helpTestRewriteCommand("SELECT e1 FROM (SELECT e1 FROM pm1.g1 WHERE (1 - 1) = (0 + 0)) AS x", //$NON-NLS-1$
+                                "SELECT e1 FROM (SELECT e1 FROM pm1.g1) AS x"); //$NON-NLS-1$
+    }
+
+    public void testExistsSubquery() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
+                                "SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
+    }
+
+    public void testCompareSubqueryANY() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE '3' = ANY (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
+                                "SELECT e1 FROM pm1.g1 WHERE '3' = SOME (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
+    }
+
+    public void testCompareSubquery() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE '3' = SOME (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
+                                "SELECT e1 FROM pm1.g1 WHERE '3' = SOME (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
+    }
+    
+    public void testCompareSubqueryUnknown() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE null = SOME (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
+                                "SELECT e1 FROM pm1.g1 WHERE null <> null"); //$NON-NLS-1$
+    }
+
+    public void testINClauseSubquery() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE '3' IN (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
+                                "SELECT e1 FROM pm1.g1 WHERE '3' IN (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
+    }
+
+    public void testRewriteXMLCriteria1() {
+        helpTestRewriteCriteria("context(pm1.g1.e1, pm1.g1.e1) = convert(5, string)", "context(pm1.g1.e1, pm1.g1.e1) = '5'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteXMLCriteria2() {
+        helpTestRewriteCriteria("context(pm1.g1.e1, convert(5, string)) = 2+3", "context(pm1.g1.e1, '5') = '5'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    // HAS Criteria
+    public void testRewriteProcedure1() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+				
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    // HAS Criteria
+    public void testRewriteProcedure2() {
+    	
+		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n";		 //$NON-NLS-1$
+		procedure = procedure + "ELSE \n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n";		 //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+				
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    // HAS Criteria
+    public void testRewriteProcedure3() {
+    	
+		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n";		 //$NON-NLS-1$
+		procedure = procedure + "ELSE \n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n";		 //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+				
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    public void testRewriteProcedure4() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (INPUT.e2 = 1)\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+				
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }    
+    
+    // CHANGING
+    public void testRewriteProcedure5() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (CHANGING.e1 = \"false\")\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e2);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    // CHANGING
+    public void testRewriteProcedure6() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (CHANGING.e1 = \"true\")\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }     
+    
+    // TRANSLATE CRITERIA
+    public void testRewriteProcedure7() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (CHANGING.e1 = \"true\")\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select e2 from pm1.g1 where TRANSLATE = CRITERIA ON (vm1.g1.e2);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT e2 FROM pm1.g1 WHERE pm1.g1.e2 = 10;\n";				 //$NON-NLS-1$
+		rewritProc = rewritProc + "END";		 //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    // TRANSLATE CRITERIA
+    public void testRewriteProcedure8() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (CHANGING.e1 = \"true\")\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select e2 from pm1.g1 where TRANSLATE = CRITERIA ON (vm1.g1.e2) with (vm1.g1.e2 = convert(sqrt(pm1.g1.e2), integer));\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "Update vm1.g1 SET e1 = \"String\", e2 =1 where e2 = 10"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT e2 FROM pm1.g1 WHERE convert(sqrt(pm1.g1.e2), integer) = 10;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    // rewrite input/ changing variables
+    public void testRewriteProcedure9() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "Declare String var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "if(var1 = 'x' or var1 = 'y')\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n";         //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2, Input.e2, CHANGING.e2, CHANGING.e1 from pm1.g1 order by CHANGING.e1;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (e1) values('x')"; //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE String var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "IF((var1 = 'x') OR (var1 = 'y'))\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2, null AS E2_0, FALSE AS E2_1, TRUE AS E1 FROM pm1.g1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+    public void testRewriteProcedure10() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1, pm1.g2 where TRANSLATE = CRITERIA ON (e2) WITH (e2 = pm1.g1.e2 + 20);\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g1 SET e1='x' where e2 = e2 + 50"; //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1, pm1.g2 WHERE (pm1.g1.e2 + 20) = ((pm1.g1.e2 + 20) + 50);\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+	// virtual group elements used in procedure in if statement(HAS CRITERIA)
+    public void testRewriteProcedure11() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE string var1;\n"; //$NON-NLS-1$
+		procedure = procedure + "var1 = INPUT.e1;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g1 SET e1=40";     //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE string var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "var1 = '40';\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+	// with complex query transform
+    public void testRewriteProcedure12() {
+        String procedure = "CREATE PROCEDURE  "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (x = CONCAT(e1 , 'z'));\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g3 SET x='x' where x =CONCAT(x , 'y')"; //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE CONCAT(e1, 'z') = CONCAT(CONCAT(e1, 'z'), 'y');\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+	// with complex query transform
+    public void testRewriteProcedure13() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (x = CONCAT(e1 , 'z'), y = convert(CONCAT(e1 , 'k'), integer));\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g3 SET x='x' where x =CONCAT(x , 'y') and y= 1"; //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE (CONCAT(e1, 'z') = CONCAT(CONCAT(e1, 'z'), 'y')) AND (convert(CONCAT(e1, 'k'), integer) = 1);\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+    public void testRewriteProcedure14() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (e4 = sqrt(e4));\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g3 SET x='x' where e4= 1"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE sqrt(e4) = 1.0;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+    public void testRewriteProcedure15() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE = CRITERIA WITH (e4 = e4/50);\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g3 SET x='x' where y= 1"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE e2 = 0;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+    public void testRewriteProcedure16() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE CRITERIA;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g3 SET x='x' where e4= 1"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE e4 = 0.02;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+    public void testRewriteProcedure17() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE LIKE CRITERIA WITH (e4 = e4/50);\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n";         //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g3 SET x='x' where e4= 1"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// Bug 8212 elements in INPUT and CHANGING special groups are cese sensitive
+    public void testRewriteProcedure18() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "Select Input.E1, Input.e2, CHANGING.e2, CHANGING.E1 from pm1.g1;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (e1, E2) values('x', 1)"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT 'x', 1, TRUE, TRUE FROM pm1.g1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// elements being set in updates are dropped if INPUT var is not available, unless a default is available
+    // Note that this test is a little odd in that it is an update inside of an insert
+    public void testRewriteProcedure19() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "update pm1.g1 set e1=Input.E1, e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (E2) values(1)"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "UPDATE pm1.g1 SET e1 = 'xyz', e2 = 1, e3 = TRUE;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// elements being set in updates are dropped if INPUT var is not available, unless a default is supplied
+    
+    //this test fails because the default for E1 'xyz' cannot be converted into a integer
+    public void testRewriteProcedure21() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "update pm1.g1 set e1=convert(Input.E1, integer)+INPUT.E2, e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (E3) values({b'true'})"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "UPDATE pm1.g1 SET e3 = TRUE;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		this.helpFailUpdateProcedure(procedure, userQuery, FakeMetadataObject.Props.INSERT_PROCEDURE);
+	}
+    
+    public void testRewriteProcedure21a() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "update pm1.g1 set e1=convert(Input.E1, integer)+INPUT.E2, e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (E1) values(1)"; //$NON-NLS-1$
+
+        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "UPDATE pm1.g1 SET e1 = null, e2 = null, e3 = TRUE;\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+                                                        FakeMetadataObject.Props.INSERT_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+
+	
+	// none of input variables on update statement changing
+    public void testRewriteProcedure22() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "update pm1.g1 set e1=convert(Input.E1, integer)+INPUT.E2, e2=Input.e2;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "update vm1.g1 set E3 = {b'true'}"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// none of input variables on update statement changing
+    public void testRewriteProcedure23() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "update pm1.g1 set e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "update vm1.g1 set E1 = 'x'"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+    
+    //with an insert, defaults are used
+    public void testRewriteProcedure23a() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "update pm1.g1 set e2=Input.e2, e3=Input.e3;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (E1) values('x')"; //$NON-NLS-1$
+
+        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "UPDATE pm1.g1 SET e2 = null, e3 = TRUE;\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+                FakeMetadataObject.Props.INSERT_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+	// elements being set in updates are dropped if INPUT var is not available
+    public void testRewriteProcedure24() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "UPDATE pm1.g1 SET e2=Input.e2 WHERE TRANSLATE LIKE CRITERIA ON (e1) WITH (e1=concat(pm1.g1.e1, \"%\"));\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g1 set E2=1 where e2 = 1 and e1 LIKE 'mnopxyz_'"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "UPDATE pm1.g1 SET e2 = 1 WHERE concat(pm1.g1.e1, '%') LIKE 'mnopxyz_';\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+
+	// INPUT vars in insert statements replaced by default variable when user's inser ignores values
+    public void testRewriteProcedure25() {
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "INSERT into pm1.g1 (e1,e2,e3,e4) values (Input.e1, Input.e2, Input.e3, Input.e4);"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "INSERT into vm1.g1 (E2) values (1)"; //$NON-NLS-1$
+
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "INSERT INTO pm1.g1 (e1, e2, e3, e4) VALUES ('xyz', 1, TRUE, 123.456);\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.INSERT_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+	public void testRewriteProcedure26() {
+		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		procedure = procedure + "Select pm1.g1.e2 from pm1.g1, pm1.g2 where TRANSLATE = CRITERIA ON (e2);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n";         //$NON-NLS-1$
+
+		String userQuery = "UPDATE vm1.g1 SET e1='x' where e2 = e2 + 50"; //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1, pm1.g2 WHERE pm1.g1.e2 = (pm1.g1.e2 + 50);\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+		assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+	
+	// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+	public void testRewriteProcedure27() {
+		String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		procedure = procedure + "Select pm1.g1.e2 from pm1.g1, pm1.g2 where TRANSLATE = CRITERIA ON (e2);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n";         //$NON-NLS-1$
+
+		String userQuery = "UPDATE vm1.g1 SET e1='x' where e2 LIKE 'xyz'"; //$NON-NLS-1$
+        
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT pm1.g1.e2 FROM pm1.g1, pm1.g2 WHERE "+FALSE_STR+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+		assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+	}
+
+    /**
+     * Per defect 9380 - 
+     * A criteria of the form  
+     * (? + 1) < (null)  
+     * caused a problem in the QueryRewriter.simplifyMathematicalCriteria method.
+     * At the beginning of the method, the null constant is rewritten so that it
+     * loses it's implicit type conversion to integer, then later on a function
+     * descriptor couldn't be found for the "minus" operation for the two types 
+     * integer and MetaMatrix's null type.
+     */
+    public void testRewriteProcedure_9380() {
+        
+        String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure = procedure + "DECLARE integer var2;\n"; //$NON-NLS-1$
+        procedure = procedure + "if((var1 + 1) < length(input.e1))\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n";         //$NON-NLS-1$
+        procedure = procedure + "var2 = INPUT.e2;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userQuery = "UPDATE vm1.g1 SET e2=30";     //$NON-NLS-1$
+        
+        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "BEGIN\n";         //$NON-NLS-1$
+        rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "DECLARE integer var2;\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "END"; //$NON-NLS-1$
+
+        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+                FakeMetadataObject.Props.UPDATE_PROCEDURE);
+
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    //base test.  no change is expected
+    public void testRewriteLookupFunction1() {
+        String criteria = "lookup('pm1.g1','e1', 'e2', 'value') = 'ab'"; //$NON-NLS-1$
+        CompareCriteria expected = (CompareCriteria)parseCriteria(criteria, FakeMetadataFactory.example1Cached()); 
+        helpTestRewriteCriteria(criteria, expected, FakeMetadataFactory.example1Cached());
+    }
+    
+    public void testRewriteLookupFunction1b() {
+        helpTestRewriteCriteria("lookup('pm1.g1','e1', 'e2', pm1.g1.e1) = 'ab'", "lookup('pm1.g1','e1', 'e2', pm1.g1.e1) = 'ab'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /** defect 11630 1 should still get rewritten as '1'*/
+    public void testRewriteLookupFunctionCompoundCriteria() {
+        String criteria = "LOOKUP('pm1.g1','e1', 'e2', 'value') IS NULL AND pm1.g1.e1='1'"; //$NON-NLS-1$
+        CompoundCriteria expected = (CompoundCriteria)parseCriteria(criteria, FakeMetadataFactory.example1Cached()); 
+        helpTestRewriteCriteria("LOOKUP('pm1.g1','e1', 'e2', 'value') IS NULL AND pm1.g1.e1=1", expected, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$ 
+    }
+
+    public void testSelectWithNoFrom() {
+        helpTestRewriteCommand("SELECT 5", "SELECT 5"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    //defect 9822
+    public void testStoredProcedure_9822() throws Exception {
+
+        QueryParser parser = new QueryParser();
+        Command command = parser.parseCommand("exec pm1.sp4(5)");             //$NON-NLS-1$
+        
+        // resolve
+        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
+        
+        // rewrite
+        Command rewriteCommand = QueryRewriter.rewrite(command, null, null, null);
+        
+        List parameters = ((StoredProcedure)rewriteCommand).getParameters();
+        
+        Iterator iter = parameters.iterator();
+        while(iter.hasNext()){
+            SPParameter param = (SPParameter)iter.next();
+            if(param.getParameterType() == ParameterInfo.IN || param.getParameterType() == ParameterInfo.INOUT){
+                assertTrue(param.getExpression() instanceof Constant);
+            }
+        }  
+    }
+    
+    public void testRewriteRecursive() {
+        Command c = helpTestRewriteCommand("SELECT e2 FROM vm1.g33", "SELECT e2 FROM vm1.g33"); //$NON-NLS-1$ //$NON-NLS-2$
+        Command innerCommand = (Command) c.getSubCommands().get(0);
+        
+        assertEquals("Inner command not rewritten", "SELECT e2 FROM pm1.g1 WHERE e2 = 2", innerCommand.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+        
+    }
+    
+    public void testRewriteFunctionThrowsEvaluationError() {
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria origCrit = parseCriteria("5 / 0 = 5", metadata); //$NON-NLS-1$
+        
+        // rewrite
+        try { 
+            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            fail("Expected QueryValidatorException due to divide by 0"); //$NON-NLS-1$
+        } catch(QueryValidatorException e) {
+            assertEquals("Unable to evaluate (5 / 0): Error while evaluating function /", e.getMessage());  //$NON-NLS-1$
+        }       
+    }
+    
+    public void testRewriteConvertThrowsEvaluationError() {
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+        Criteria origCrit = parseCriteria("convert('x', integer) = 0", metadata); //$NON-NLS-1$
+        
+        // rewrite
+        try { 
+            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            fail("Expected QueryValidatorException due to invalid string"); //$NON-NLS-1$
+        } catch(QueryValidatorException e) {
+            assertEquals("Unable to convert 'x' of type [string] to the expected type [integer].", e.getMessage()); //$NON-NLS-1$
+        }       
+    }
+    
+    public void testDefect13458() {
+    	
+		String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n";		 //$NON-NLS-1$
+		procedure = procedure + "IF (HAS = CRITERIA ON (vm1.g1.e1))\n"; //$NON-NLS-1$
+		procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+		procedure = procedure + "Select vm1.g1.e1 from vm1.g1 where HAS = CRITERIA ON (vm1.g1.e1);\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		procedure = procedure + "END\n"; //$NON-NLS-1$
+		
+		String userQuery = "delete from vm1.g1 where e1='1'"; //$NON-NLS-1$
+		
+		String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "BEGIN\n";		 //$NON-NLS-1$
+		rewritProc = rewritProc + "SELECT vm1.g1.e1 FROM vm1.g1;\n"; //$NON-NLS-1$
+		rewritProc = rewritProc + "END"; //$NON-NLS-1$
+		
+		String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+				FakeMetadataObject.Props.DELETE_PROCEDURE);				
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    public void testRewriteCase1954() {
+        helpTestRewriteCriteria("convert(pm1.g1.e2, string) = '3'", "pm1.g1.e2 = 3"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCase1954a() {
+        helpTestRewriteCriteria("cast(pm1.g1.e2 as string) = '3'", "pm1.g1.e2 = 3"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCase1954b() throws Exception{
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached(); 
+
+        // Have to hand-build the criteria, because 3.0 gets parsed as a Float by default
+        // pm1.g1.e4 = 3.0
+        CompareCriteria expected = new CompareCriteria();
+        ElementSymbol leftElement = new ElementSymbol("pm1.g1.e4"); //$NON-NLS-1$
+        Constant constant = new Constant(new Double(3.0), DataTypeManager.DefaultDataClasses.DOUBLE);
+        expected.setLeftExpression(leftElement);
+        expected.setRightExpression(constant);
+        // resolve against metadata
+        QueryResolver.resolveCriteria(expected, metadata);
+        
+        helpTestRewriteCriteria("convert(pm1.g1.e4, string) = '3'", expected, metadata); //$NON-NLS-1$ 
+    }    
+
+    public void testRewriteCase1954c() {
+        helpTestRewriteCriteria("convert(pm1.g1.e1, string) = 'x'", "pm1.g1.e1 = 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }    
+
+    /** Test some other type besides 'string' has no effect */
+    public void testRewriteCase1954d() {
+        helpTestRewriteCriteria("convert(pm1.g1.e1, timestamp) = {ts '2005-01-03 00:00:00.0'}", "convert(pm1.g1.e1, timestamp) = {ts '2005-01-03 00:00:00.0'}"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /** Test some other type besides 'string' has no effect */
+    public void testRewriteCase1954e() {
+        helpTestRewriteCriteria("convert(pm1.g1.e4, integer) = 2", "convert(pm1.g1.e4, integer) = 2"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /** Check that this fails, x is not convertable to an int */
+    public void testRewriteCase1954f() {
+        helpTestRewriteCriteria("convert(pm1.g1.e2, string) = 'x'", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    /** Check that this returns true, x is not convertable to an int */
+    public void testRewriteCase1954f1() {
+        helpTestRewriteCriteria("convert(pm1.g1.e2, string) != 'x'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCase1954Set() {
+        helpTestRewriteCriteria("convert(pm1.g1.e2, string) in ('2', '3')", "pm1.g1.e2 IN (2,3)"); //$NON-NLS-1$ //$NON-NLS-2$
+    }    
+
+    public void testRewriteCase1954SetA() {
+        helpTestRewriteCriteria("convert(pm1.g1.e2, string) in ('2', 'x')", "convert(pm1.g1.e2, string) in ('2', 'x')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }    
+    
+    public void testRewriteCase1954SetB() {
+        helpTestRewriteCriteria("cast(pm1.g1.e2 as string) in ('2', '3')", "pm1.g1.e2 IN (2,3)"); //$NON-NLS-1$ //$NON-NLS-2$
+    }    
+    
+    public void testRewriteCase1954SetC() {
+        helpTestRewriteCriteria("concat(pm1.g1.e2, 'string') in ('2', '3')", "concat(pm1.g1.e2, 'string') in ('2', '3')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }    
+
+    public void testRewriteCase1954SetD() {
+        helpTestRewriteCriteria("convert(pm1.g1.e2, string) in ('2', pm1.g1.e1)", "convert(pm1.g1.e2, string) in ('2', pm1.g1.e1)"); //$NON-NLS-1$ //$NON-NLS-2$
+    }      
+    
+    // First WHEN always true, so rewrite as THEN expression
+    public void testRewriteCaseExpr1() {
+        helpTestRewriteCriteria("case when 0=0 then 1 else 2 end = 1", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    // First WHEN always false, so rewrite as ELSE expression
+    public void testRewriteCaseExpr2() {
+        helpTestRewriteCriteria("case when 0=1 then 1 else 2 end = 1", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    // First WHEN can't be rewritten, so no changes
+    public void testRewriteCaseExpr3() {
+        helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then 1 else 2 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 1 ELSE 2 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCaseExpr4() {
+        helpTestRewriteCriteria("lookup('pm1.g1', 'e2', 'e1', case when 1=1 then pm1.g1.e1 end) = 0", "lookup('pm1.g1', 'e2', 'e1', pm1.g1.e1) = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    // First WHEN always false, so remove it
+    public void testRewriteCaseExpr5() {
+        helpTestRewriteCriteria("case when 0=1 then 1 when 0 = pm1.g1.e2 then 2 else 3 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 2 ELSE 3 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCaseExprForCase5413aFrom502() {
+        helpTestRewriteCriteria("pm1.g2.e1 = case when 0 = pm1.g1.e2 then 2 else 2 end", "pm1.g2.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCaseExprForCase5413bFrom502() {
+        helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then null else null end IS NULL", TRUE_STR); //$NON-NLS-1$ 
+    }
+    
+    
+    public void testRewriteCaseExprForCase5413a() {
+        helpTestRewriteCriteria("pm1.g2.e1 = case when 0 = pm1.g1.e2 then 2 else 2 end", "pm1.g2.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteCaseExprForCase5413b() {
+        helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then null else null end IS NULL", TRUE_STR); //$NON-NLS-1$ 
+    }
+
+    // First WHEN always true, so rewrite as THEN expression
+    public void testRewriteSearchedCaseExpr1() {
+        helpTestRewriteCriteria("case 0 when 0 then 1 else 2 end = 1", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    // First WHEN always false, so rewrite as ELSE expression
+    public void testRewriteSearchedCaseExpr2() {
+        helpTestRewriteCriteria("case 0 when 1 then 1 else 2 end = 1", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteSearchedCaseExpr3() {
+        helpTestRewriteCriteria("case 0 when pm1.g1.e2 then 1 else 2 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 1 ELSE 2 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteSearchedCaseExpr4() {
+        String criteria = "lookup('pm1.g1', 'e2', 'e1', null) = 0"; //$NON-NLS-1$
+        CompareCriteria expected = (CompareCriteria)parseCriteria(criteria, FakeMetadataFactory.example1Cached()); 
+        helpTestRewriteCriteria("lookup('pm1.g1', 'e2', 'e1', case 0 when 1 then pm1.g1.e1 end) = 0", expected, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$
+    }
+
+    // First WHEN always false, so remove it
+    public void testRewriteSearchedCaseExpr5() {
+        helpTestRewriteCriteria("case 0 when 1 then 1 when pm1.g1.e2 then 2 else 3 end = 1", "CASE WHEN pm1.g1.e2 = 0 THEN 2 ELSE 3 END = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testDefect16879_1(){
+    	helpTestRewriteCommand("SELECT decodestring(e1, 'a, b') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testDefect16879_2(){
+    	helpTestRewriteCommand("SELECT decodestring(e1, 'a, b, c, d') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 = 'c' THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testDefect16879_3(){
+    	helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testDefect16879_4(){
+    	helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b, c, d') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 = 'c' THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testDefect16879_5(){
+        helpTestRewriteCommand("SELECT decodeinteger(e1, 'null, b, c, d') FROM pm1.g1", "SELECT CASE WHEN e1 IS NULL THEN 'b' WHEN e1 = 'c' THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testDefect16879_6(){
+        helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b, null, d') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 IS NULL THEN 'd' ELSE e1 END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testDefect16879_7(){
+        helpTestRewriteCommand("SELECT decodeinteger(e1, 'a, b, null, d, e') FROM pm1.g1", "SELECT CASE WHEN e1 = 'a' THEN 'b' WHEN e1 IS NULL THEN 'd' ELSE 'e' END FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
     public void testCaseExpressionThatResolvesToNull() {
         String sqlBefore = "SELECT CASE 'x' WHEN 'Old Inventory System' THEN NULL WHEN 'New Inventory System' THEN NULL END"; //$NON-NLS-1$
         String sqlAfter = "SELECT null"; //$NON-NLS-1$
 
         Command cmd = helpTestRewriteCommand( sqlBefore, sqlAfter );
         
-        ExpressionSymbol es = (ExpressionSymbol)cmd.getProjectedSymbols().get(0);
+        DerivedColumn es = (DerivedColumn)cmd.getProjectedSymbols().get(0);
         assertEquals( DataTypeManager.DefaultDataClasses.STRING, es.getType() );
     }
 
-
-    //note that the env is now treated as deterministic, however it is really only deterministic within a session
-    public void testRewriteExecEnv() throws Exception {
-        Command command = QueryParser.getQueryParser().parseCommand("exec pm1.sq2(env('sessionid'))");             //$NON-NLS-1$
-        
-        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
-        
-        CommandContext context = new CommandContext();
-        Properties props = new Properties();
-        props.setProperty(ContextProperties.SESSION_ID, "1"); //$NON-NLS-1$
-        context.setEnvironmentProperties(props);
-        Command rewriteCommand = QueryRewriter.rewrite(command, null, null, context);
-        
-        assertEquals("SELECT e1, e2 FROM pm1.g1 WHERE e1 = '1'", rewriteCommand.toString()); //$NON-NLS-1$
-    }
-
-    public void testRewriteExecCase6455() throws Exception {
-        Command command = QueryParser.getQueryParser().parseCommand("exec pm1.sq2(env('sessionid')) OPTION PLANONLY DEBUG");             //$NON-NLS-1$
-        
-        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
-        
-        CommandContext context = new CommandContext();
-        Properties props = new Properties();
-        props.setProperty(ContextProperties.SESSION_ID, "1"); //$NON-NLS-1$
-        context.setEnvironmentProperties(props);
-        Command rewriteCommand = QueryRewriter.rewrite(command, null, null, context);
-        
-        assertEquals("SELECT e1, e2 FROM pm1.g1 WHERE e1 = '1' OPTION PLANONLY DEBUG", rewriteCommand.toString()); //$NON-NLS-1$
-    }
-
-
-    public void testRewriteNestedFunctions() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 where convert(parsedate(e1, 'yyyy-MM-dd'), string) = '2006-07-01'", "SELECT e1 FROM pm1.g1 WHERE e1 = '2006-07-01'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteWithReference() {
-        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 where parsetimestamp(e1, 'yyyy-MM-dd') != ?", "SELECT e1 FROM pm1.g1 WHERE e1 <> formattimestamp(?, 'yyyy-MM-dd')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewiteJoinCriteria() {
-        helpTestRewriteCommand("SELECT pm1.g1.e1 FROM pm1.g1 inner join pm1.g2 on (pm1.g1.e1 = null)", "SELECT pm1.g1.e1 FROM pm1.g1 INNER JOIN pm1.g2 ON 1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewiteCompoundCriteria() {
-        helpTestRewriteCriteria("(pm1.g1.e1 = 1 and pm1.g1.e2 = 2) and (pm1.g1.e3 = 1 and pm1.g1.e4 = 2)", "(pm1.g1.e1 = '1') AND (pm1.g1.e2 = 2) AND (pm1.g1.e3 = TRUE) AND (pm1.g1.e4 = 2.0)"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteWhile() throws Exception {
-        
-        String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n";       //$NON-NLS-1$
-        procedure = procedure + "while (1 = 1)\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "Select vm1.g1.e1 from vm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        
-        String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-
-        QueryMetadataInterface metadata = FakeMetadataFactory.exampleUpdateProc(FakeMetadataObject.Props.INSERT_PROCEDURE, procedure);
-        
-        QueryParser parser = new QueryParser();
-        Command userCommand = parser.parseCommand(userQuery);
-        QueryResolver.resolveCommand(userCommand, metadata);
-        
-        try {       
-            QueryRewriter.rewrite(userCommand, null, metadata, null);
-            fail("exception expected"); //$NON-NLS-1$
-        } catch (QueryValidatorException e) {
-            assertEquals("Infinite loop detected, procedure will not be executed.", e.getMessage()); //$NON-NLS-1$
-        }
-                
-    }
-    
-    public void testRewriteWhile1() {
-        
-        String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n";       //$NON-NLS-1$
-        procedure = procedure + "while (1 = 0)\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "Select vm1.g1.e1 from vm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        
-        String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-        
-        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "BEGIN\n";         //$NON-NLS-1$
-        rewritProc = rewritProc + "END"; //$NON-NLS-1$
-        
-        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-                FakeMetadataObject.Props.INSERT_PROCEDURE);
-                
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    /**
-     * Tests that VariableSubstitutionVisitor does not cause an NPE on count(*)
-     */
-    public void testRewriteProcedureWithCount() {
-        
-        String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n";         //$NON-NLS-1$
-        procedure = procedure + "Select count(*) from pm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        
-        String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
-        
-        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
-        rewritProc = rewritProc + "BEGIN\n";         //$NON-NLS-1$
-        rewritProc = rewritProc + "SELECT COUNT(*) FROM pm1.g1;\n";         //$NON-NLS-1$
-        rewritProc = rewritProc + "END"; //$NON-NLS-1$
-        
-        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
-                FakeMetadataObject.Props.INSERT_PROCEDURE);
-                
-        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
-    }
-    
-    /**
-     * Test to ensure the update changing list retains e1 = ?
-     */
-    public void testVariableSubstitutionVisitor() throws Exception {
-        String procedure1 = "CREATE PROCEDURE  "; //$NON-NLS-1$
-        procedure1 += "BEGIN\n"; //$NON-NLS-1$
-        procedure1 += "DECLARE string var1 = INPUT.e1;\n"; //$NON-NLS-1$
-        procedure1 += "ROWS_UPDATED = UPDATE vm1.g2 SET e1=var1;\n"; //$NON-NLS-1$
-        procedure1 += "END"; //$NON-NLS-1$
-        
-        String procedure2 = "CREATE PROCEDURE "; //$NON-NLS-1$
-        procedure2 += "BEGIN\n"; //$NON-NLS-1$
-        procedure2 += "DECLARE integer var1;\n"; //$NON-NLS-1$
-        procedure2 += "IF (INPUT.e1 = 1)\n"; //$NON-NLS-1$
-        procedure2 += "ROWS_UPDATED = 5;\n"; //$NON-NLS-1$
-        procedure2 += "ELSE\n"; //$NON-NLS-1$
-        procedure2 += "ROWS_UPDATED = 5;\n"; //$NON-NLS-1$
-        procedure2 += "END"; //$NON-NLS-1$
-
-        String userUpdateStr = "UPDATE vm1.g1 SET e1 = 'x' WHERE e2 = 5"; //$NON-NLS-1$
-        
-        FakeMetadataFacade metadata = FakeMetadataFactory.exampleUpdateProc(FakeMetadataObject.Props.UPDATE_PROCEDURE, procedure1, procedure2);
-        
-        Update command = (Update)helpTestRewriteCommand(userUpdateStr, userUpdateStr, metadata);
-                     
-        String expected = "CREATE PROCEDURE\nBEGIN\nDECLARE string var1 = 'x';\nROWS_UPDATED = UPDATE vm1.g2 SET e1 = var1;\nEND"; //$NON-NLS-1$
-        
-        assertEquals(expected, command.getSubCommand().toString());
-    }
-    
-    public void testRemoveEmptyLoop() {
-        String procedure1 = "CREATE virtual PROCEDURE  "; //$NON-NLS-1$
-        procedure1 += "BEGIN\n"; //$NON-NLS-1$
-        procedure1 += "loop on (select e1 from pm1.g1) as myCursor\n"; //$NON-NLS-1$
-        procedure1 += "begin\n"; //$NON-NLS-1$
-        procedure1 += "end\n"; //$NON-NLS-1$
-        procedure1 += "select e1 from pm1.g1;\n"; //$NON-NLS-1$
-        procedure1 += "END"; //$NON-NLS-1$
-        
-        String expected = "CREATE VIRTUAL PROCEDURE\nBEGIN\nSELECT e1 FROM pm1.g1;\nEND"; //$NON-NLS-1$
-        
-        helpTestRewriteCommand(procedure1, expected);
-    }
-    
-    public void testRewriteDeclare() {
-        String procedure1 = "CREATE virtual PROCEDURE  "; //$NON-NLS-1$
-        procedure1 += "BEGIN\n"; //$NON-NLS-1$
-        procedure1 += "declare integer x = 1 + 1;\n"; //$NON-NLS-1$
-        procedure1 += "END"; //$NON-NLS-1$
-        
-        String expected = "CREATE VIRTUAL PROCEDURE\nBEGIN\nDECLARE integer x = 2;\nEND"; //$NON-NLS-1$
-        
-        helpTestRewriteCommand(procedure1, expected);
-    }
-      
-    public void testRewriteUnionJoin() {
-        String sql = "select pm1.g1.e1 from pm1.g1 union join pm1.g2 where g1.e1 = 1"; //$NON-NLS-1$
-        String expected = "SELECT pm1.g1.e1 FROM pm1.g1 FULL OUTER JOIN pm1.g2 ON 1 = 0 WHERE g1.e1 = '1'"; //$NON-NLS-1$
-                
-        helpTestRewriteCommand(sql, expected);        
-    }
-
-    public void testRewriteNonNullDependentFunction() {
-        helpTestRewriteCriteria("pm1.g1.e1 = concat(null, pm1.g1.e2)", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteInWithNull() {
-        helpTestRewriteCriteria("convert(null, string) in (pm1.g1.e1, pm1.g1.e2)", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteXMLCriteriaCases5630And5640() {
-        helpTestRewriteCommand("select * from xmltest.doc1 where node1 = null", "SELECT * FROM xmltest.doc1 WHERE node1 = null"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteCorrelatedSubqueryInHaving() {
-        String sql = "select pm1.g1.e1 from pm1.g1 group by pm1.g1.e1 having pm1.g1.e1 in (select pm1.g1.e1 from pm1.g2)"; //$NON-NLS-1$
-        String expected = "SELECT pm1.g1.e1 FROM pm1.g1 GROUP BY pm1.g1.e1 HAVING pm1.g1.e1 IN (SELECT pm1.g1.e1 FROM pm1.g2)"; //$NON-NLS-1$
-                
-        Query query = (Query)helpTestRewriteCommand(sql, expected);
-        
-        List refs = new LinkedList();
-        
-        CorrelatedReferenceCollectorVisitor.collectReferences(query, Arrays.asList(new Object[] {new GroupSymbol("pm1.g1")}), refs);//$NON-NLS-1$
-        
-        assertEquals(1, refs.size());
-    }
-    
-    public void testRewriteSelectInto() {
-        String sql = "select distinct pm1.g1.e1 into #temp from pm1.g1"; //$NON-NLS-1$
-        String expected = "SELECT DISTINCT pm1.g1.e1 INTO #temp FROM pm1.g1"; //$NON-NLS-1$
-                
-        helpTestRewriteCommand(sql, expected);        
-    }
-    
-    /**
-     * Accounts for type change with duplicate names
-     */
-    public void testRewriteSelectInto1() {
-        String sql = "select distinct e2, e2, e3, e4 into pm1.g1 from pm1.g2"; //$NON-NLS-1$
-        String expected = "SELECT PM1_G1_1.E2 AS E2, PM1_G1_1.E2_0, PM1_G1_1.E3, PM1_G1_1.E4 INTO pm1.g1 FROM (SELECT DISTINCT e2, e2 AS E2_0, e3, e4 FROM pm1.g2) AS pm1_g1_1"; //$NON-NLS-1$
-                
-        helpTestRewriteCommand(sql, expected);        
-    }
-    
-    public void testUnionQueryNullInOneBranch() throws Exception {
-        verifyProjectedTypesOnUnionBranches("SELECT e1, e2 FROM pm1.g1 UNION ALL SELECT e1, null FROM pm1.g2", //$NON-NLS-1$
-                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER });
-    }
-    
-    public void testUnionQueryNullInOneBranch2() throws Exception {
-        verifyProjectedTypesOnUnionBranches("SELECT e1, e2 FROM pm1.g1 UNION ALL SELECT e1, e2 FROM pm1.g2 UNION ALL SELECT e1, null FROM pm1.g2", //$NON-NLS-1$
-                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER });
-    }
-
-    public void testUnionQueryNullInOneBranch3() throws Exception {
-        verifyProjectedTypesOnUnionBranches("SELECT e1, null FROM pm1.g1 UNION ALL SELECT e1, null FROM pm1.g2 UNION ALL SELECT e1, e2 FROM pm1.g2", //$NON-NLS-1$
-                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER });
-    }
-
-    public void testUnionQueryNullInAllBranches() throws Exception {
-        verifyProjectedTypesOnUnionBranches("SELECT e1, null FROM pm1.g1 UNION ALL SELECT e1, null FROM pm1.g2 UNION ALL SELECT e1, null FROM pm1.g2", //$NON-NLS-1$
-                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING });
-    }
-    
-    public void testUnionQueryWithTypeConversion() throws Exception {
-        verifyProjectedTypesOnUnionBranches("SELECT e1 FROM pm1.g1 UNION ALL SELECT e2 FROM pm1.g2", //$NON-NLS-1$
-                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING});
-    }
-
-    private void verifyProjectedTypesOnUnionBranches(String unionQuery, Class[] types) throws QueryValidatorException, QueryParserException, QueryResolverException, MetaMatrixComponentException {
-        SetQuery union = (SetQuery)QueryParser.getQueryParser().parseCommand(unionQuery);
-        QueryResolver.resolveCommand(union, FakeMetadataFactory.example1Cached());
-        
-        union = (SetQuery)QueryRewriter.rewrite(union, null, FakeMetadataFactory.example1Cached(), null);
-        
-        for (QueryCommand query : union.getQueryCommands()) {
-            List projSymbols = query.getProjectedSymbols();
-            for(int i=0; i<projSymbols.size(); i++) {
-                assertEquals("Found type mismatch at column " + i, types[i], ((SingleElementSymbol) projSymbols.get(i)).getType()); //$NON-NLS-1$
-            }                
-        }
-    }
-    
-    public void testRewiteOrderBy() {
-        helpTestRewriteCommand("SELECT 1+1 as a FROM pm1.g1 order by a", "SELECT 2 AS a FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewiteOrderBy1() {
-        helpTestRewriteCommand("SELECT 1+1 as a FROM pm1.g1 union select pm1.g2.e1 from pm1.g2 order by a", "SELECT '2' AS a FROM pm1.g1 UNION SELECT pm1.g2.e1 FROM pm1.g2 ORDER BY a"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    /**
-     * The rewrite creates inline view to do the type conversion.
-     * 
-     * It also ensures that all project symbols are uniquely named in the inline view
-     */
-    public void testSelectIntoWithOrderByAndTypeConversion() throws Exception {
-        String procedure = "CREATE VIRTUAL PROCEDURE\n"; //$NON-NLS-1$
-        procedure += "BEGIN\n";       //$NON-NLS-1$
-        procedure += "CREATE local temporary table temp (x string, y integer, z integer);\n";       //$NON-NLS-1$
-        procedure += "Select pm1.g1.e2, 1 as x, 2 as x into temp from pm1.g1 order by pm1.g1.e2 limit 1;\n"; //$NON-NLS-1$
-        procedure += "Select x from temp;\n"; //$NON-NLS-1$
-        procedure += "END\n"; //$NON-NLS-1$
-        
-        helpTestRewriteCommand(procedure, "CREATE VIRTUAL PROCEDURE\nBEGIN\nCREATE LOCAL TEMPORARY TABLE temp (x string, y integer, z integer);\nSELECT TEMP_1.E2 AS E2, TEMP_1.X, TEMP_1.X_0 INTO temp FROM (SELECT pm1.g1.e2, 1 AS x, 2 AS X_0 FROM pm1.g1 ORDER BY pm1.g1.e2 LIMIT 1) AS temp_1;\nSELECT x FROM temp;\nEND"); //$NON-NLS-1$
-    }
-    
-    
-    public void testInsertWithQuery() throws Exception {
-        String sql = "insert into pm1.g1 select e1, e2, e3, e4 from pm1.g2 union select e1, e2, e3, e4 from pm1.g2"; //$NON-NLS-1$
-        
-        helpTestRewriteCommand(sql, "SELECT PM1_G1_1.E1, PM1_G1_1.E2, PM1_G1_1.E3, PM1_G1_1.E4 INTO pm1.g1 FROM (SELECT e1, e2, e3, e4 FROM pm1.g2 UNION SELECT e1, e2, e3, e4 FROM pm1.g2) AS pm1_g1_1"); //$NON-NLS-1$
-    }
-    
-    public void testRewriteNot() {
-        helpTestRewriteCriteria("not(not(pm1.g1.e1 = 1 + 1))", "pm1.g1.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteQueryWithNoFrom() {
-        String sql = "select 1 as a order by a"; //$NON-NLS-1$
-        
-        helpTestRewriteCommand(sql, "SELECT 1 AS a"); //$NON-NLS-1$
-    }
-    
-    public void testOrderByDuplicateRemoval() {
-        String sql = "SELECT pm1.g1.e1, pm1.g1.e1 as c1234567890123456789012345678901234567890 FROM pm1.g1 ORDER BY c1234567890123456789012345678901234567890, e1 "; //$NON-NLS-1$
-        helpTestRewriteCommand(sql, "SELECT pm1.g1.e1, pm1.g1.e1 AS c1234567890123456789012345678901234567890 FROM pm1.g1 ORDER BY c1234567890123456789012345678901234567890"); //$NON-NLS-1$
-    }
-    
-    /**
-     * Case 4814
-     */
-    public void testVirtualRightOuterJoinSwap() throws Exception {
-        String sql = "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM (select * from BQT1.smalla) sa RIGHT OUTER JOIN (select BQT1.mediumb.intkey from BQT1.mediumb) mb ON sa.IntKey = mb.IntKey"; //$NON-NLS-1$
-        helpTestRewriteCommand(sql, "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM (SELECT BQT1.mediumb.intkey FROM BQT1.mediumb) AS mb LEFT OUTER JOIN (SELECT * FROM BQT1.smalla) AS sa ON sa.IntKey = mb.IntKey", FakeMetadataFactory.exampleBQTCached()); //$NON-NLS-1$
-    }
-    
-    /**
-     * Case 4814
-     */
-    public void testVirtualRightOuterJoinSwap1() throws Exception {
-        String sql = "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM ((select * from BQT1.smalla) sa inner join BQT1.smallb on sa.intkey = smallb.intkey) RIGHT OUTER JOIN (select BQT1.mediumb.intkey from BQT1.mediumb) mb ON sa.IntKey = mb.IntKey"; //$NON-NLS-1$
-        helpTestRewriteCommand(sql, "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM (SELECT BQT1.mediumb.intkey FROM BQT1.mediumb) AS mb LEFT OUTER JOIN ((SELECT * FROM BQT1.smalla) AS sa INNER JOIN BQT1.smallb ON sa.intkey = smallb.intkey) ON sa.IntKey = mb.IntKey", FakeMetadataFactory.exampleBQTCached()); //$NON-NLS-1$
-    }
-    
-    public void testRewriteConcat2() {
-        helpTestRewriteCriteria("concat2('a','b') = 'ab'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewriteConcat2_1() {
-        helpTestRewriteCriteria("concat2(null, null) is null", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteConcat2_2() throws Exception {
-        helpTestRewriteCriteria("concat2(pm1.g1.e1, null) = 'xyz'", "CASE WHEN pm1.g1.e1 IS NULL THEN null ELSE concat(ifnull(pm1.g1.e1, ''), '') END = 'xyz'", true); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteConcat2_3() throws Exception {
-        helpTestRewriteCriteria("concat2(pm1.g1.e1, convert(pm1.g1.e2, string)) = 'xyz'", "CASE WHEN (pm1.g1.e1 IS NULL) AND (convert(pm1.g1.e2, string) IS NULL) THEN null ELSE concat(ifnull(pm1.g1.e1, ''), ifnull(convert(pm1.g1.e2, string), '')) END = 'xyz'", true); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    public void testRewriteConcat2_4() throws Exception {
-        helpTestRewriteCriteria("concat2('a', pm1.g1.e1) = 'xyz'", "concat('a', ifnull(pm1.g1.e1, '')) = 'xyz'"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-    
-    public void testRewiteEvaluatableAggregate() {
-    	helpTestRewriteCommand("select pm1.g1.e1, max(1) from pm1.g1", "SELECT pm1.g1.e1, 1 FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+
+    //note that the env is now treated as deterministic, however it is really only deterministic within a session
+    public void testRewriteExecEnv() throws Exception {
+        Command command = QueryParser.getQueryParser().parseCommand("exec pm1.sq2(env('sessionid'))");             //$NON-NLS-1$
+        
+        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
+        
+        CommandContext context = new CommandContext();
+        Properties props = new Properties();
+        props.setProperty(ContextProperties.SESSION_ID, "1"); //$NON-NLS-1$
+        context.setEnvironmentProperties(props);
+        Command rewriteCommand = QueryRewriter.rewrite(command, null, null, context);
+        
+        assertEquals("SELECT e1, e2 FROM pm1.g1 WHERE e1 = '1'", rewriteCommand.toString()); //$NON-NLS-1$
     }
+
+    public void testRewriteExecCase6455() throws Exception {
+        Command command = QueryParser.getQueryParser().parseCommand("exec pm1.sq2(env('sessionid')) OPTION PLANONLY DEBUG");             //$NON-NLS-1$
+        
+        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
+        
+        CommandContext context = new CommandContext();
+        Properties props = new Properties();
+        props.setProperty(ContextProperties.SESSION_ID, "1"); //$NON-NLS-1$
+        context.setEnvironmentProperties(props);
+        Command rewriteCommand = QueryRewriter.rewrite(command, null, null, context);
+        
+        assertEquals("SELECT e1, e2 FROM pm1.g1 WHERE e1 = '1' OPTION PLANONLY DEBUG", rewriteCommand.toString()); //$NON-NLS-1$
+    }
+
+
+    public void testRewriteNestedFunctions() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 where convert(parsedate(e1, 'yyyy-MM-dd'), string) = '2006-07-01'", "SELECT e1 FROM pm1.g1 WHERE e1 = '2006-07-01'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
     
+    public void testRewriteWithReference() {
+        helpTestRewriteCommand("SELECT e1 FROM pm1.g1 where parsetimestamp(e1, 'yyyy-MM-dd') != ?", "SELECT e1 FROM pm1.g1 WHERE e1 <> formattimestamp(?, 'yyyy-MM-dd')"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewiteJoinCriteria() {
+        helpTestRewriteCommand("SELECT pm1.g1.e1 FROM pm1.g1 inner join pm1.g2 on (pm1.g1.e1 = null)", "SELECT pm1.g1.e1 FROM pm1.g1 INNER JOIN pm1.g2 ON 1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewiteCompoundCriteria() {
+        helpTestRewriteCriteria("(pm1.g1.e1 = 1 and pm1.g1.e2 = 2) and (pm1.g1.e3 = 1 and pm1.g1.e4 = 2)", "(pm1.g1.e1 = '1') AND (pm1.g1.e2 = 2) AND (pm1.g1.e3 = TRUE) AND (pm1.g1.e4 = 2.0)"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteWhile() throws Exception {
+        
+        String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n";       //$NON-NLS-1$
+        procedure = procedure + "while (1 = 1)\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "Select vm1.g1.e1 from vm1.g1;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        
+        String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+
+        QueryMetadataInterface metadata = FakeMetadataFactory.exampleUpdateProc(FakeMetadataObject.Props.INSERT_PROCEDURE, procedure);
+        
+        QueryParser parser = new QueryParser();
+        Command userCommand = parser.parseCommand(userQuery);
+        QueryResolver.resolveCommand(userCommand, metadata);
+        
+        try {       
+            QueryRewriter.rewrite(userCommand, null, metadata, null);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (QueryValidatorException e) {
+            assertEquals("Infinite loop detected, procedure will not be executed.", e.getMessage()); //$NON-NLS-1$
+        }
+                
+    }
+    
+    public void testRewriteWhile1() {
+        
+        String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n";       //$NON-NLS-1$
+        procedure = procedure + "while (1 = 0)\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+        procedure = procedure + "Select vm1.g1.e1 from vm1.g1;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        
+        String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+        
+        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "BEGIN\n";         //$NON-NLS-1$
+        rewritProc = rewritProc + "END"; //$NON-NLS-1$
+        
+        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+                FakeMetadataObject.Props.INSERT_PROCEDURE);
+                
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    /**
+     * Tests that VariableSubstitutionVisitor does not cause an NPE on count(*)
+     */
+    public void testRewriteProcedureWithCount() {
+        
+        String procedure = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        procedure = procedure + "BEGIN\n";         //$NON-NLS-1$
+        procedure = procedure + "Select count(*) from pm1.g1;\n"; //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+        
+        String userQuery = "Insert into vm1.g1 (e1, e2) values (\"String\", 1)"; //$NON-NLS-1$
+        
+        String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
+        rewritProc = rewritProc + "BEGIN\n";         //$NON-NLS-1$
+        rewritProc = rewritProc + "SELECT COUNT(*) FROM pm1.g1;\n";         //$NON-NLS-1$
+        rewritProc = rewritProc + "END"; //$NON-NLS-1$
+        
+        String procReturned = this.getReWrittenProcedure(procedure, userQuery, 
+                FakeMetadataObject.Props.INSERT_PROCEDURE);
+                
+        assertEquals("Rewritten command was not expected", rewritProc, procReturned); //$NON-NLS-1$
+    }
+    
+    /**
+     * Test to ensure the update changing list retains e1 = ?
+     */
+    public void testVariableSubstitutionVisitor() throws Exception {
+        String procedure1 = "CREATE PROCEDURE  "; //$NON-NLS-1$
+        procedure1 += "BEGIN\n"; //$NON-NLS-1$
+        procedure1 += "DECLARE string var1 = INPUT.e1;\n"; //$NON-NLS-1$
+        procedure1 += "ROWS_UPDATED = UPDATE vm1.g2 SET e1=var1;\n"; //$NON-NLS-1$
+        procedure1 += "END"; //$NON-NLS-1$
+        
+        String procedure2 = "CREATE PROCEDURE "; //$NON-NLS-1$
+        procedure2 += "BEGIN\n"; //$NON-NLS-1$
+        procedure2 += "DECLARE integer var1;\n"; //$NON-NLS-1$
+        procedure2 += "IF (INPUT.e1 = 1)\n"; //$NON-NLS-1$
+        procedure2 += "ROWS_UPDATED = 5;\n"; //$NON-NLS-1$
+        procedure2 += "ELSE\n"; //$NON-NLS-1$
+        procedure2 += "ROWS_UPDATED = 5;\n"; //$NON-NLS-1$
+        procedure2 += "END"; //$NON-NLS-1$
+
+        String userUpdateStr = "UPDATE vm1.g1 SET e1 = 'x' WHERE e2 = 5"; //$NON-NLS-1$
+        
+        FakeMetadataFacade metadata = FakeMetadataFactory.exampleUpdateProc(FakeMetadataObject.Props.UPDATE_PROCEDURE, procedure1, procedure2);
+        
+        Update command = (Update)helpTestRewriteCommand(userUpdateStr, userUpdateStr, metadata);
+                     
+        String expected = "CREATE PROCEDURE\nBEGIN\nDECLARE string var1 = 'x';\nROWS_UPDATED = UPDATE vm1.g2 SET e1 = var1;\nEND"; //$NON-NLS-1$
+        
+        assertEquals(expected, command.getSubCommand().toString());
+    }
+    
+    public void testRemoveEmptyLoop() {
+        String procedure1 = "CREATE virtual PROCEDURE  "; //$NON-NLS-1$
+        procedure1 += "BEGIN\n"; //$NON-NLS-1$
+        procedure1 += "loop on (select e1 from pm1.g1) as myCursor\n"; //$NON-NLS-1$
+        procedure1 += "begin\n"; //$NON-NLS-1$
+        procedure1 += "end\n"; //$NON-NLS-1$
+        procedure1 += "select e1 from pm1.g1;\n"; //$NON-NLS-1$
+        procedure1 += "END"; //$NON-NLS-1$
+        
+        String expected = "CREATE VIRTUAL PROCEDURE\nBEGIN\nSELECT e1 FROM pm1.g1;\nEND"; //$NON-NLS-1$
+        
+        helpTestRewriteCommand(procedure1, expected);
+    }
+    
+    public void testRewriteDeclare() {
+        String procedure1 = "CREATE virtual PROCEDURE  "; //$NON-NLS-1$
+        procedure1 += "BEGIN\n"; //$NON-NLS-1$
+        procedure1 += "declare integer x = 1 + 1;\n"; //$NON-NLS-1$
+        procedure1 += "END"; //$NON-NLS-1$
+        
+        String expected = "CREATE VIRTUAL PROCEDURE\nBEGIN\nDECLARE integer x = 2;\nEND"; //$NON-NLS-1$
+        
+        helpTestRewriteCommand(procedure1, expected);
+    }
+      
+    public void testRewriteUnionJoin() {
+        String sql = "select pm1.g1.e1 from pm1.g1 union join pm1.g2 where g1.e1 = 1"; //$NON-NLS-1$
+        String expected = "SELECT pm1.g1.e1 FROM pm1.g1 FULL OUTER JOIN pm1.g2 ON 1 = 0 WHERE g1.e1 = '1'"; //$NON-NLS-1$
+                
+        helpTestRewriteCommand(sql, expected);        
+    }
+
+    public void testRewriteNonNullDependentFunction() {
+        helpTestRewriteCriteria("pm1.g1.e1 = concat(null, pm1.g1.e2)", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteInWithNull() {
+        helpTestRewriteCriteria("convert(null, string) in (pm1.g1.e1, pm1.g1.e2)", "null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteXMLCriteriaCases5630And5640() {
+        helpTestRewriteCommand("select * from xmltest.doc1 where node1 = null", "SELECT * FROM xmltest.doc1 WHERE node1 = null"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteCorrelatedSubqueryInHaving() {
+        String sql = "select pm1.g1.e1 from pm1.g1 group by pm1.g1.e1 having pm1.g1.e1 in (select pm1.g1.e1 from pm1.g2)"; //$NON-NLS-1$
+        String expected = "SELECT pm1.g1.e1 FROM pm1.g1 GROUP BY pm1.g1.e1 HAVING pm1.g1.e1 IN (SELECT pm1.g1.e1 FROM pm1.g2)"; //$NON-NLS-1$
+                
+        Query query = (Query)helpTestRewriteCommand(sql, expected);
+        
+        List refs = new LinkedList();
+        
+        CorrelatedReferenceCollectorVisitor.collectReferences(query, Arrays.asList(new Object[] {new GroupSymbol("pm1.g1")}), refs);//$NON-NLS-1$
+        
+        assertEquals(1, refs.size());
+    }
+    
+    public void testRewriteSelectInto() {
+        String sql = "select distinct pm1.g1.e1 into #temp from pm1.g1"; //$NON-NLS-1$
+        String expected = "SELECT DISTINCT pm1.g1.e1 INTO #temp FROM pm1.g1"; //$NON-NLS-1$
+                
+        helpTestRewriteCommand(sql, expected);        
+    }
+    
+    /**
+     * Accounts for type change with duplicate names
+     */
+    public void testRewriteSelectInto1() {
+        String sql = "select distinct e2, e2, e3, e4 into pm1.g1 from pm1.g2"; //$NON-NLS-1$
+        String expected = "SELECT PM1_G1_1.E2 AS E2, PM1_G1_1.E2_0, PM1_G1_1.E3, PM1_G1_1.E4 INTO pm1.g1 FROM (SELECT DISTINCT e2, e2 AS E2_0, e3, e4 FROM pm1.g2) AS pm1_g1_1"; //$NON-NLS-1$
+                
+        helpTestRewriteCommand(sql, expected);        
+    }
+    
+    public void testUnionQueryNullInOneBranch() throws Exception {
+        verifyProjectedTypesOnUnionBranches("SELECT e1, e2 FROM pm1.g1 UNION ALL SELECT e1, null FROM pm1.g2", //$NON-NLS-1$
+                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER });
+    }
+    
+    public void testUnionQueryNullInOneBranch2() throws Exception {
+        verifyProjectedTypesOnUnionBranches("SELECT e1, e2 FROM pm1.g1 UNION ALL SELECT e1, e2 FROM pm1.g2 UNION ALL SELECT e1, null FROM pm1.g2", //$NON-NLS-1$
+                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER });
+    }
+
+    public void testUnionQueryNullInOneBranch3() throws Exception {
+        verifyProjectedTypesOnUnionBranches("SELECT e1, null FROM pm1.g1 UNION ALL SELECT e1, null FROM pm1.g2 UNION ALL SELECT e1, e2 FROM pm1.g2", //$NON-NLS-1$
+                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER });
+    }
+
+    public void testUnionQueryNullInAllBranches() throws Exception {
+        verifyProjectedTypesOnUnionBranches("SELECT e1, null FROM pm1.g1 UNION ALL SELECT e1, null FROM pm1.g2 UNION ALL SELECT e1, null FROM pm1.g2", //$NON-NLS-1$
+                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING });
+    }
+    
+    public void testUnionQueryWithTypeConversion() throws Exception {
+        verifyProjectedTypesOnUnionBranches("SELECT e1 FROM pm1.g1 UNION ALL SELECT e2 FROM pm1.g2", //$NON-NLS-1$
+                                            new Class[] { DataTypeManager.DefaultDataClasses.STRING});
+    }
+
+    private void verifyProjectedTypesOnUnionBranches(String unionQuery, Class[] types) throws QueryValidatorException, QueryParserException, QueryResolverException, MetaMatrixComponentException {
+        SetQuery union = (SetQuery)QueryParser.getQueryParser().parseCommand(unionQuery);
+        QueryResolver.resolveCommand(union, FakeMetadataFactory.example1Cached());
+        
+        union = (SetQuery)QueryRewriter.rewrite(union, null, FakeMetadataFactory.example1Cached(), null);
+        
+        for (QueryCommand query : union.getQueryCommands()) {
+            List projSymbols = query.getProjectedSymbols();
+            for(int i=0; i<projSymbols.size(); i++) {
+                assertEquals("Found type mismatch at column " + i, types[i], ((SingleElementSymbol) projSymbols.get(i)).getType()); //$NON-NLS-1$
+            }                
+        }
+    }
+    
+    public void testRewiteOrderBy() {
+        helpTestRewriteCommand("SELECT 1+1 as a FROM pm1.g1 order by a", "SELECT 2 AS a FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewiteOrderBy1() {
+        helpTestRewriteCommand("SELECT 1+1 as a FROM pm1.g1 union select pm1.g2.e1 from pm1.g2 order by a", "SELECT '2' AS a FROM pm1.g1 UNION SELECT pm1.g2.e1 FROM pm1.g2 ORDER BY a"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    /**
+     * The rewrite creates inline view to do the type conversion.
+     * 
+     * It also ensures that all project symbols are uniquely named in the inline view
+     */
+    public void testSelectIntoWithOrderByAndTypeConversion() throws Exception {
+        String procedure = "CREATE VIRTUAL PROCEDURE\n"; //$NON-NLS-1$
+        procedure += "BEGIN\n";       //$NON-NLS-1$
+        procedure += "CREATE local temporary table temp (x string, y integer, z integer);\n";       //$NON-NLS-1$
+        procedure += "Select pm1.g1.e2, 1 as x, 2 as x into temp from pm1.g1 order by pm1.g1.e2 limit 1;\n"; //$NON-NLS-1$
+        procedure += "Select x from temp;\n"; //$NON-NLS-1$
+        procedure += "END\n"; //$NON-NLS-1$
+        
+        helpTestRewriteCommand(procedure, "CREATE VIRTUAL PROCEDURE\nBEGIN\nCREATE LOCAL TEMPORARY TABLE temp (x string, y integer, z integer);\nSELECT TEMP_1.E2 AS E2, TEMP_1.X, TEMP_1.X_0 INTO temp FROM (SELECT pm1.g1.e2, 1 AS x, 2 AS X_0 FROM pm1.g1 ORDER BY pm1.g1.e2 LIMIT 1) AS temp_1;\nSELECT x FROM temp;\nEND"); //$NON-NLS-1$
+    }
+    
+    
+    public void testInsertWithQuery() throws Exception {
+        String sql = "insert into pm1.g1 select e1, e2, e3, e4 from pm1.g2 union select e1, e2, e3, e4 from pm1.g2"; //$NON-NLS-1$
+        
+        helpTestRewriteCommand(sql, "SELECT PM1_G1_1.E1, PM1_G1_1.E2, PM1_G1_1.E3, PM1_G1_1.E4 INTO pm1.g1 FROM (SELECT e1, e2, e3, e4 FROM pm1.g2 UNION SELECT e1, e2, e3, e4 FROM pm1.g2) AS pm1_g1_1"); //$NON-NLS-1$
+    }
+    
+    public void testRewriteNot() {
+        helpTestRewriteCriteria("not(not(pm1.g1.e1 = 1 + 1))", "pm1.g1.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteQueryWithNoFrom() {
+        String sql = "select 1 as a order by a"; //$NON-NLS-1$
+        
+        helpTestRewriteCommand(sql, "SELECT 1 AS a"); //$NON-NLS-1$
+    }
+    
+    public void testOrderByDuplicateRemoval() {
+        String sql = "SELECT pm1.g1.e1, pm1.g1.e1 as c1234567890123456789012345678901234567890 FROM pm1.g1 ORDER BY c1234567890123456789012345678901234567890, e1 "; //$NON-NLS-1$
+        helpTestRewriteCommand(sql, "SELECT pm1.g1.e1, pm1.g1.e1 AS c1234567890123456789012345678901234567890 FROM pm1.g1 ORDER BY c1234567890123456789012345678901234567890"); //$NON-NLS-1$
+    }
+    
+    /**
+     * Case 4814
+     */
+    public void testVirtualRightOuterJoinSwap() throws Exception {
+        String sql = "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM (select * from BQT1.smalla) sa RIGHT OUTER JOIN (select BQT1.mediumb.intkey from BQT1.mediumb) mb ON sa.IntKey = mb.IntKey"; //$NON-NLS-1$
+        helpTestRewriteCommand(sql, "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM (SELECT BQT1.mediumb.intkey FROM BQT1.mediumb) AS mb LEFT OUTER JOIN (SELECT * FROM BQT1.smalla) AS sa ON sa.IntKey = mb.IntKey", FakeMetadataFactory.exampleBQTCached()); //$NON-NLS-1$
+    }
+    
+    /**
+     * Case 4814
+     */
+    public void testVirtualRightOuterJoinSwap1() throws Exception {
+        String sql = "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM ((select * from BQT1.smalla) sa inner join BQT1.smallb on sa.intkey = smallb.intkey) RIGHT OUTER JOIN (select BQT1.mediumb.intkey from BQT1.mediumb) mb ON sa.IntKey = mb.IntKey"; //$NON-NLS-1$
+        helpTestRewriteCommand(sql, "SELECT sa.IntKey AS sa_IntKey, mb.IntKey AS mb_IntKey FROM (SELECT BQT1.mediumb.intkey FROM BQT1.mediumb) AS mb LEFT OUTER JOIN ((SELECT * FROM BQT1.smalla) AS sa INNER JOIN BQT1.smallb ON sa.intkey = smallb.intkey) ON sa.IntKey = mb.IntKey", FakeMetadataFactory.exampleBQTCached()); //$NON-NLS-1$
+    }
+    
+    public void testRewriteConcat2() {
+        helpTestRewriteCriteria("concat2('a','b') = 'ab'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewriteConcat2_1() {
+        helpTestRewriteCriteria("concat2(null, null) is null", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteConcat2_2() throws Exception {
+        helpTestRewriteCriteria("concat2(pm1.g1.e1, null) = 'xyz'", "CASE WHEN pm1.g1.e1 IS NULL THEN null ELSE concat(ifnull(pm1.g1.e1, ''), '') END = 'xyz'", true); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteConcat2_3() throws Exception {
+        helpTestRewriteCriteria("concat2(pm1.g1.e1, convert(pm1.g1.e2, string)) = 'xyz'", "CASE WHEN (pm1.g1.e1 IS NULL) AND (convert(pm1.g1.e2, string) IS NULL) THEN null ELSE concat(ifnull(pm1.g1.e1, ''), ifnull(convert(pm1.g1.e2, string), '')) END = 'xyz'", true); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testRewriteConcat2_4() throws Exception {
+        helpTestRewriteCriteria("concat2('a', pm1.g1.e1) = 'xyz'", "concat('a', ifnull(pm1.g1.e1, '')) = 'xyz'"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testRewiteEvaluatableAggregate() {
+    	helpTestRewriteCommand("select pm1.g1.e1, max(1) from pm1.g1", "SELECT pm1.g1.e1, 1 FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
     public void testRewriteFromUnixTime() throws Exception {
     	TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$
     	try {
@@ -2122,5 +2122,5 @@
         }
         
     }
-
-}
+
+}

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestAliasSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestAliasSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestAliasSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -26,14 +26,14 @@
 
 import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.Constant;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 
 public class TestAliasSymbol extends TestCase {
 
     public void testAliasEquals() {
-        AliasSymbol a1 = new AliasSymbol("X", new ExpressionSymbol("x", new Constant(1))); //$NON-NLS-1$ //$NON-NLS-2$
-        AliasSymbol a2 = new AliasSymbol("X", new ExpressionSymbol("x", new Constant(2))); //$NON-NLS-1$ //$NON-NLS-2$
-        AliasSymbol a3 = new AliasSymbol("x", new ExpressionSymbol("x", new Constant(1))); //$NON-NLS-1$ //$NON-NLS-2$
+        AliasSymbol a1 = new AliasSymbol("X", new DerivedColumn("x", new Constant(1))); //$NON-NLS-1$ //$NON-NLS-2$
+        AliasSymbol a2 = new AliasSymbol("X", new DerivedColumn("x", new Constant(2))); //$NON-NLS-1$ //$NON-NLS-2$
+        AliasSymbol a3 = new AliasSymbol("x", new DerivedColumn("x", new Constant(1))); //$NON-NLS-1$ //$NON-NLS-2$
         
         assertEquals(a1, a3); //just a different case for the alias
         
@@ -41,7 +41,7 @@
     }
     
     public void testClone() {
-        AliasSymbol a1 = new AliasSymbol("X", new ExpressionSymbol("x", new Constant(1))); //$NON-NLS-1$ //$NON-NLS-2$
+        AliasSymbol a1 = new AliasSymbol("X", new DerivedColumn("x", new Constant(1))); //$NON-NLS-1$ //$NON-NLS-2$
         a1.setOutputName("foo"); //$NON-NLS-1$
         AliasSymbol clone = (AliasSymbol)a1.clone();
         assertEquals(a1, clone);

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestExpressionSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestExpressionSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestExpressionSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -24,7 +24,7 @@
 
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 
 import junit.framework.TestCase;
 
@@ -34,8 +34,8 @@
     public void testExpressionHashCode() {
         Expression expr1 = new Constant(new Integer(1));
         Expression expr2 = new Constant(new Integer(2));
-        ExpressionSymbol symbol1 = new ExpressionSymbol("foo", expr1); //$NON-NLS-1$
-        ExpressionSymbol symbol2 = new ExpressionSymbol("bar", expr2); //$NON-NLS-1$
+        DerivedColumn symbol1 = new DerivedColumn("foo", expr1); //$NON-NLS-1$
+        DerivedColumn symbol2 = new DerivedColumn("bar", expr2); //$NON-NLS-1$
         
         assertFalse(symbol1.hashCode() == symbol2.hashCode());
     }
@@ -43,8 +43,8 @@
     public void testExpressionHashCode1() {
         Expression expr1 = new Constant(new Integer(1));
         Expression expr2 = new Constant(new Integer(1));
-        ExpressionSymbol symbol1 = new ExpressionSymbol("foo", expr1); //$NON-NLS-1$
-        ExpressionSymbol symbol2 = new ExpressionSymbol("bar", expr2); //$NON-NLS-1$
+        DerivedColumn symbol1 = new DerivedColumn("foo", expr1); //$NON-NLS-1$
+        DerivedColumn symbol2 = new DerivedColumn("bar", expr2); //$NON-NLS-1$
         
         assertTrue(symbol1.hashCode() == symbol2.hashCode());
     }

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestSelect.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestSelect.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/lang/TestSelect.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -28,8 +28,8 @@
 import junit.framework.TestCase;
 
 import com.metamatrix.core.util.UnitTestUtil;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 
 public class TestSelect extends TestCase {
@@ -59,7 +59,7 @@
 	    select.addSymbol(new ElementSymbol("a"));	 //$NON-NLS-1$
 	    select.addSymbol(new ElementSymbol("b"));	 //$NON-NLS-1$
 	    select.addSymbol(new ElementSymbol("c")); //$NON-NLS-1$
-	    select.addSymbol(new AliasSymbol("Z", new ElementSymbol("ZZ 9 Plural Z Alpha"))); //$NON-NLS-1$ //$NON-NLS-2$
+	    select.addSymbol(new DerivedColumn("Z", new ElementSymbol("ZZ 9 Plural Z Alpha"), true)); //$NON-NLS-1$ //$NON-NLS-2$
 	    return select;	
 	}
 			

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/symbol/TestAggregateSymbol.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/symbol/TestAggregateSymbol.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/symbol/TestAggregateSymbol.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -53,12 +53,12 @@
 		return new Function("+", new Expression[] { sampleElement(), sampleConstant() }); //$NON-NLS-1$
 	}
 
-	private void helpParser(AggregateSymbol as, String expected) {
+	private void helpParser(Aggregate as, String expected) {
 		String toString = as.toString();		
 		assertEquals("Parser string does not match", expected, toString);		 //$NON-NLS-1$
 	}
 	
-	private void helpEquals(AggregateSymbol as1, AggregateSymbol as2, boolean equal) {
+	private void helpEquals(Aggregate as1, Aggregate as2, boolean equal) {
 		if(equal) {
 			assertTrue("Aggregate symbols should be equal: " + as1 + ", " + as2, as1.equals(as2)); //$NON-NLS-1$ //$NON-NLS-2$
 		} else {
@@ -70,105 +70,105 @@
 	// ################################## ACTUAL TESTS ################################
 	
 	public void testParser1() {
-		AggregateSymbol as = new AggregateSymbol("count", ReservedWords.COUNT, false, sampleElement()); //$NON-NLS-1$
+		Aggregate as = new Aggregate(ReservedWords.COUNT, false, sampleElement()); //$NON-NLS-1$
 		helpParser(as, "COUNT(m.g.c)"); //$NON-NLS-1$
 	}
 
 	public void testParser2() {
-		AggregateSymbol as = new AggregateSymbol("count", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate as = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
 		helpParser(as, "COUNT(DISTINCT m.g.c)"); //$NON-NLS-1$
 	}
 
 	public void testParser3() {
-		AggregateSymbol as = new AggregateSymbol("x", ReservedWords.MIN, false, sampleConstant()); //$NON-NLS-1$
+		Aggregate as = new Aggregate(ReservedWords.MIN, false, sampleConstant()); //$NON-NLS-1$
 		helpParser(as, "MIN(5)"); //$NON-NLS-1$
 	}
 
 	public void testParser4() {
-		AggregateSymbol as = new AggregateSymbol("x", ReservedWords.MAX, false, sampleFunction()); //$NON-NLS-1$
+		Aggregate as = new Aggregate(ReservedWords.MAX, false, sampleFunction()); //$NON-NLS-1$
 		helpParser(as, "MAX((m.g.c + 5))"); //$NON-NLS-1$
 	}
 
 	public void testParser5() {
-		AggregateSymbol as = new AggregateSymbol("x", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+		Aggregate as = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
 		helpParser(as, "COUNT(*)"); //$NON-NLS-1$
 	}
 		
 	public void testEquals1() { 
-		AggregateSymbol as = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate as = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
 		helpEquals(as, as, true);		
 	}
 
 	public void testEquals2() { 
-		AggregateSymbol as1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
-		AggregateSymbol as2 = (AggregateSymbol) as1.clone();
+		Aggregate as1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate as2 = (Aggregate) as1.clone();
 		helpEquals(as1, as2, true);		
 	}
 
     //just changing the name of an aggregatesymbol doesn't matter
 	public void testEquals3() { 
-		AggregateSymbol as1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
-		AggregateSymbol as2 = new AggregateSymbol("y", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate as1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate as2 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
 		helpEquals(as1, as2, true);		
 	}
 	
 	public void testEquals4() { 
-		AggregateSymbol as1 = new AggregateSymbol("count", ReservedWords.COUNT, false, null); //$NON-NLS-1$
-		AggregateSymbol as2 = (AggregateSymbol) as1.clone();
+		Aggregate as1 = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
+		Aggregate as2 = (Aggregate) as1.clone();
 		helpEquals(as1, as2, true);		
 	}
 
 	public void testSelfEquivalence(){
-		AggregateSymbol test = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate test = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
 		int equals = 0;
 		UnitTestUtil.helpTestEquivalence(equals, test, test);
 	}
 
 	public void testEquivalence(){
-		AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
-		AggregateSymbol test2 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate test1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate test2 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
 		int equals = 0;
 		UnitTestUtil.helpTestEquivalence(equals, test1, test2);
 	}
     
     public void testEquivalenceCountStar(){
-        AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.COUNT, false, null); //$NON-NLS-1$
-        AggregateSymbol test2 = new AggregateSymbol("x", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+        Aggregate test1 = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
+        Aggregate test2 = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
         int equals = 0;
         UnitTestUtil.helpTestEquivalence(equals, test1, test2);
     }
 
 	public void testEquivalenceCaseInsens(){
-		AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
-		AggregateSymbol test2 = new AggregateSymbol("X", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate test1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate test2 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
 		int equals = 0;
 		UnitTestUtil.helpTestEquivalence(equals, test1, test2);
 	}
     
     public void testNonEquivalenceUsingDiffElements(){ 
-        AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$ 
-        AggregateSymbol test2 = new AggregateSymbol("X", ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$ 
+        Aggregate test1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$ 
+        Aggregate test2 = new Aggregate(ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$ 
         int equals = -1; 
         UnitTestUtil.helpTestEquivalence(equals, test1, test2); 
     } 
 	
 	public void testNonEquivalence(){
-		AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
-		AggregateSymbol test2 = new AggregateSymbol("y", ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$
+		Aggregate test1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+		Aggregate test2 = new Aggregate(ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$
 		int equals = -1;
 		UnitTestUtil.helpTestEquivalence(equals, test1, test2);
 	}
     
     public void testNonEquivalence1(){
-        AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
-        AggregateSymbol test2 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$
+        Aggregate test1 = new Aggregate(ReservedWords.COUNT, true, sampleElement()); //$NON-NLS-1$
+        Aggregate test2 = new Aggregate(ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$
         int equals = -1;
         UnitTestUtil.helpTestEquivalence(equals, test1, test2);
     }
     
     public void testNonEquivalence2(){
-        AggregateSymbol test1 = new AggregateSymbol("x", ReservedWords.MAX, true, sampleElement()); //$NON-NLS-1$
-        AggregateSymbol test2 = new AggregateSymbol("x", ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$
+        Aggregate test1 = new Aggregate(ReservedWords.MAX, true, sampleElement()); //$NON-NLS-1$
+        Aggregate test2 = new Aggregate(ReservedWords.COUNT, true, sampleElement2()); //$NON-NLS-1$
         int equals = -1;
         UnitTestUtil.helpTestEquivalence(equals, test1, test2);
     }

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestSQLStringVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestSQLStringVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestSQLStringVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -76,15 +76,14 @@
 import com.metamatrix.query.sql.proc.HasCriteria;
 import com.metamatrix.query.sql.proc.IfStatement;
 import com.metamatrix.query.sql.proc.RaiseErrorStatement;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
+import com.metamatrix.query.sql.symbol.Aggregate;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Reference;
@@ -592,7 +591,7 @@
 	public void testOrderBy2() {
 		OrderBy ob = new OrderBy();
 		ob.addVariable(new ElementSymbol("e1")); //$NON-NLS-1$
-		ob.addVariable(new AliasSymbol("x", new ElementSymbol("e2"))); //$NON-NLS-1$ //$NON-NLS-2$
+		ob.addVariable(new ElementSymbol("x")); //$NON-NLS-1$
 		
 		helpTest(ob, "ORDER BY e1, x");     //$NON-NLS-1$
 	}
@@ -1051,48 +1050,48 @@
 	}
 	
 	public void testAggregateSymbol1() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.COUNT, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		Aggregate agg = new Aggregate(ReservedWords.COUNT, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(agg, "COUNT('abc')"); //$NON-NLS-1$
 	}
 	
 	public void testAggregateSymbol2() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.COUNT, true, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		Aggregate agg = new Aggregate(ReservedWords.COUNT, true, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(agg, "COUNT(DISTINCT 'abc')"); //$NON-NLS-1$
 	}
 	
 	public void testAggregateSymbol3() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.COUNT, false, null); //$NON-NLS-1$
+		Aggregate agg = new Aggregate(ReservedWords.COUNT, false, null); //$NON-NLS-1$
 		helpTest(agg, "COUNT(*)"); //$NON-NLS-1$
 	}
 	
 	public void testAggregateSymbol4() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.AVG, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		Aggregate agg = new Aggregate(ReservedWords.AVG, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(agg, "AVG('abc')"); //$NON-NLS-1$
 	}
 	
 	public void testAggregateSymbol5() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.SUM, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		Aggregate agg = new Aggregate(ReservedWords.SUM, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(agg, "SUM('abc')"); //$NON-NLS-1$
 	}
 	
 	public void testAggregateSymbol6() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.MIN, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		Aggregate agg = new Aggregate(ReservedWords.MIN, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(agg, "MIN('abc')"); //$NON-NLS-1$
 	}
 	
 	public void testAggregateSymbol7() {
-		AggregateSymbol agg = new AggregateSymbol("abc", ReservedWords.MAX, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		Aggregate agg = new Aggregate(ReservedWords.MAX, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(agg, "MAX('abc')"); //$NON-NLS-1$
 	}
 	
 	public void testAliasSymbol1() {
-	    AliasSymbol as = new AliasSymbol("x", new ElementSymbol("element")); //$NON-NLS-1$ //$NON-NLS-2$
+	    DerivedColumn as = new DerivedColumn("x", new ElementSymbol("element"), true); //$NON-NLS-1$ //$NON-NLS-2$
 	    helpTest(as, "element AS x"); //$NON-NLS-1$
 	}
 
 	// Test alias symbol with reserved word 
 	public void testAliasSymbol2() {
-	    AliasSymbol as = new AliasSymbol("select", new ElementSymbol("element")); //$NON-NLS-1$ //$NON-NLS-2$
+	    DerivedColumn as = new DerivedColumn("select", new ElementSymbol("element"), true); //$NON-NLS-1$ //$NON-NLS-2$
 	    helpTest(as, "element AS \"select\""); //$NON-NLS-1$
 	}
 
@@ -1186,7 +1185,7 @@
     }
 
     public void testExpressionSymbol1() {
-		ExpressionSymbol expr = new ExpressionSymbol("abc", new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
+		DerivedColumn expr = new DerivedColumn("abc", new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
 		helpTest(expr, "'abc'"); //$NON-NLS-1$
     }
 
@@ -1824,7 +1823,7 @@
 
         Select s2 = new Select();
         s2.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
-        s2.addSymbol(new ExpressionSymbol("blargh", new ScalarSubquery(q1))); //$NON-NLS-1$
+        s2.addSymbol(new DerivedColumn("blargh", new ScalarSubquery(q1))); //$NON-NLS-1$
         From f2 = new From();
         f2.addGroup(new GroupSymbol("m.g2"));        //$NON-NLS-1$
         Criteria left = new SubqueryCompareCriteria(new ElementSymbol("e3"), q1, SubqueryCompareCriteria.GE, SubqueryCompareCriteria.ANY); //$NON-NLS-1$
@@ -1923,12 +1922,12 @@
         String expected = "SELECT 'A' AS FOO UNION SELECT 'B' AS FOO"; //$NON-NLS-1$
         
         Select s1 = new Select();
-        s1.addSymbol(new AliasSymbol("FOO", new ExpressionSymbol("xxx", new Constant("A")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s1.addSymbol(new DerivedColumn("FOO", new Constant("A"), true)); //$NON-NLS-1$ //$NON-NLS-2$
         Query q1 = new Query();
         q1.setSelect(s1);
 
         Select s2 = new Select();
-        s2.addSymbol(new AliasSymbol("FOO", new ExpressionSymbol("xxx", new Constant("B")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s2.addSymbol(new DerivedColumn("FOO", new Constant("B"), true)); //$NON-NLS-1$ //$NON-NLS-2$ 
         Query q2 = new Query();
         q2.setSelect(s2);
         
@@ -1948,12 +1947,12 @@
         String expected = "SELECT 'A' AS FOO UNION SELECT 'B' AS FOO"; //$NON-NLS-1$
         
         Select s1 = new Select();
-        s1.addSymbol(new AliasSymbol("FOO", new ExpressionSymbol("xxx", new Constant("A")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s1.addSymbol(new DerivedColumn("FOO", new Constant("A"), true)); //$NON-NLS-1$ //$NON-NLS-2$ 
         Query q1 = new Query();
         q1.setSelect(s1);
 
         Select s2 = new Select();
-        s2.addSymbol(new AliasSymbol("FOO", new ExpressionSymbol("yyy", new Constant("B")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        s2.addSymbol(new DerivedColumn("FOO", new Constant("B"), true)); //$NON-NLS-1$ //$NON-NLS-2$ 
         Query q2 = new Query();
         q2.setSelect(s2);
         
@@ -1978,7 +1977,7 @@
 
     public void testLimit() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);
@@ -1988,7 +1987,7 @@
     
     public void testLimitWithOffset() {
         Query query = new Query();
-        Select select = new Select(Arrays.asList(new Object[] {new AllSymbol()}));
+        Select select = new Select(Arrays.asList(new AllSymbol()));
         From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
         query.setSelect(select);
         query.setFrom(from);

Modified: branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestStaticSymbolMappingVisitor.java
===================================================================
--- branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestStaticSymbolMappingVisitor.java	2009-03-03 17:12:09 UTC (rev 531)
+++ branches/symbol_refactoring_61/engine/src/test/java/com/metamatrix/query/sql/visitor/TestStaticSymbolMappingVisitor.java	2009-03-03 17:26:43 UTC (rev 532)
@@ -48,13 +48,12 @@
 import com.metamatrix.query.sql.navigator.DeepPreOrderNavigator;
 import com.metamatrix.query.sql.proc.CriteriaSelector;
 import com.metamatrix.query.sql.proc.TranslateCriteria;
-import com.metamatrix.query.sql.symbol.AliasSymbol;
 import com.metamatrix.query.sql.symbol.AllInGroupSymbol;
 import com.metamatrix.query.sql.symbol.AllSymbol;
 import com.metamatrix.query.sql.symbol.Constant;
+import com.metamatrix.query.sql.symbol.DerivedColumn;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
-import com.metamatrix.query.sql.symbol.ExpressionSymbol;
 import com.metamatrix.query.sql.symbol.Function;
 import com.metamatrix.query.sql.symbol.GroupSymbol;
 import com.metamatrix.query.sql.symbol.Symbol;
@@ -193,7 +192,7 @@
 	    OrderBy ob = new OrderBy();
 	    ob.addVariable(exampleElement(true, 0));
 	    ob.addVariable(exampleElement(true, 1));
-	    ob.addVariable(new AliasSymbol("abc", exampleElement(true, 2))); //$NON-NLS-1$
+	    ob.addVariable(new DerivedColumn("abc", exampleElement(true, 2), true)); //$NON-NLS-1$
 	    helpTest(ob, getSymbolMap());	    
 	}
 	
@@ -219,7 +218,7 @@
 	
 	public void testVisitSelect4() { 
 		Select select = new Select();
-		select.addSymbol( new ExpressionSymbol(
+		select.addSymbol( new DerivedColumn(
 			"x", new Function("length", new Expression[] {exampleElement(true, 0)})) );    //$NON-NLS-1$ //$NON-NLS-2$
 		select.addSymbol( new AllInGroupSymbol("abc.*") ); //$NON-NLS-1$
 		select.addSymbol( exampleElement(true, 1) );
@@ -256,7 +255,7 @@
 	}
 
 	public void testVisitAliasSymbol() {
-		AliasSymbol as = new AliasSymbol("abc", exampleElement(true, 0)); //$NON-NLS-1$
+		DerivedColumn as = new DerivedColumn("abc", exampleElement(true, 0), true); //$NON-NLS-1$
 		helpTest(as, getSymbolMap());
 	}
 	




More information about the teiid-commits mailing list