[teiid-commits] teiid SVN: r2428 - in trunk/engine/src: main/java/org/teiid/query/processor/proc and 18 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Sun Aug 8 12:21:56 EDT 2010


Author: shawkins
Date: 2010-08-08 12:21:55 -0400 (Sun, 08 Aug 2010)
New Revision: 2428

Added:
   trunk/engine/src/main/java/org/teiid/query/sql/proc/ExpressionStatement.java
Modified:
   trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
   trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolveVirtualGroupCriteriaVisitor.java
   trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/SetCriteria.java
   trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java
   trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/AssignmentStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/BreakStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/ContinueStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/DeclareStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/IfStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/LoopStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseErrorStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/Statement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/WhileStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/symbol/ScalarSubquery.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/CommandCollectorVisitor.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
   trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
   trunk/engine/src/main/java/org/teiid/query/validator/Validator.java
   trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
   trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
   trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java
   trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
   trunk/engine/src/test/java/org/teiid/query/sql/lang/TestSetCriteria.java
   trunk/engine/src/test/java/org/teiid/query/sql/proc/TestAssignmentStatement.java
   trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
   trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
Log:
TEIID-168 fixing last checkin TEIID-1190 refining procedure logic

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -61,7 +61,6 @@
 import org.teiid.query.sql.proc.Statement;
 import org.teiid.query.sql.proc.WhileStatement;
 import org.teiid.query.sql.symbol.Expression;
-import org.teiid.query.sql.symbol.ScalarSubquery;
 import org.teiid.query.sql.visitor.CommandCollectorVisitor;
 import org.teiid.query.util.CommandContext;
 
@@ -216,12 +215,8 @@
                 
                 assignInstr.setVariable(assignStmt.getVariable());
                 
-				if(assignStmt.hasCommand()) {
-					assignInstr.setExpression(new ScalarSubquery(assignStmt.getCommand()));
-				} else if (assignStmt.hasExpression()) {
-					Expression asigExpr = assignStmt.getExpression();
-                    assignInstr.setExpression(asigExpr);
-				}
+				Expression asigExpr = assignStmt.getExpression();
+                assignInstr.setExpression(asigExpr);
                 if(debug) {
                 	analysisRecord.println("\tASSIGNMENT\n" + statement); //$NON-NLS-1$
                 }
@@ -233,12 +228,8 @@
             	instruction = error;
             	RaiseErrorStatement res = (RaiseErrorStatement)statement;
                 
-				if(res.hasCommand()) {
-					error.setExpression(new ScalarSubquery(res.getCommand()));
-				} else if (res.hasExpression()) {
-					Expression asigExpr = res.getExpression();
-					error.setExpression(asigExpr);
-				}
+				Expression asigExpr = res.getExpression();
+				error.setExpression(asigExpr);
                 if(debug) {
                 	analysisRecord.println("\tERROR STATEMENT:\n" + statement); //$NON-NLS-1$ 
                 }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -38,7 +38,7 @@
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.core.id.IDGenerator;
 import org.teiid.core.types.DataTypeManager;
-import org.teiid.language.SQLConstants;
+import org.teiid.dqp.internal.process.Request;
 import org.teiid.language.SQLConstants.Reserved;
 import org.teiid.logging.LogManager;
 import org.teiid.query.analysis.AnalysisRecord;
@@ -65,6 +65,7 @@
 import org.teiid.query.sql.symbol.SingleElementSymbol;
 import org.teiid.query.sql.util.VariableContext;
 import org.teiid.query.util.CommandContext;
+import org.teiid.query.validator.ValidationVisitor;
 
 
 /**
@@ -168,7 +169,9 @@
 			// create a new set of variables including vars
 			Map nameValueMap = createVariableValuesMap(localContext);
             nameValueMap.putAll(QueryResolver.getVariableValues(parentProcCommand.getUserCommand(), metadata));
-            // validation visitor?
+            ValidationVisitor visitor = new ValidationVisitor();
+            visitor.setUpdateProc(parentProcCommand);
+            Request.validateWithVisitor(visitor, metadata, command);
 
             if (dynamicCommand.getAsColumns() != null
 					&& !dynamicCommand.getAsColumns().isEmpty()) {

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -255,15 +255,6 @@
         
         public void visit(ScalarSubquery obj) {
             resolveSubQuery(obj, this.currentGroups);
-            
-            Collection<SingleElementSymbol> projSymbols = obj.getCommand().getProjectedSymbols();
-
-            //Scalar subquery should have one projected symbol (query with one expression
-            //in SELECT or stored procedure execution that returns a single value).
-            if(projSymbols.size() != 1) {
-                QueryResolverException qre = new QueryResolverException(QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0032, obj));
-                throw new TeiidRuntimeException(qre);
-            }
         }
         
         public void visit(ExistsCriteria obj) {

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -62,6 +62,7 @@
 import org.teiid.query.sql.proc.CommandStatement;
 import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
 import org.teiid.query.sql.proc.DeclareStatement;
+import org.teiid.query.sql.proc.ExpressionStatement;
 import org.teiid.query.sql.proc.IfStatement;
 import org.teiid.query.sql.proc.LoopStatement;
 import org.teiid.query.sql.proc.Statement;
@@ -241,25 +242,21 @@
             case Statement.TYPE_ERROR:
             case Statement.TYPE_ASSIGNMENT:
             case Statement.TYPE_DECLARE:
-				AssignmentStatement assStmt = (AssignmentStatement) statement;
+				ExpressionStatement exprStmt = (ExpressionStatement) statement;
                 //first resolve the value.  this ensures the value cannot use the variable being defined
-            	if (assStmt.getValue() != null) {
-					if (assStmt.hasCommand()) {
-						Command cmd = assStmt.getCommand();
-						resolveEmbeddedCommand(metadata, externalGroups, cmd, analysis);
-					} else if (assStmt.hasExpression()) {
-                        Expression expr = assStmt.getExpression();
-                        for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr)) {
-                        	resolveEmbeddedCommand(metadata, externalGroups, container.getCommand(), analysis);
-                        }
-                        ResolverVisitor.resolveLanguageObject(expr, null, externalGroups, metadata);
+            	if (exprStmt.getExpression() != null) {
+                    Expression expr = exprStmt.getExpression();
+                    for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr)) {
+                    	resolveEmbeddedCommand(metadata, externalGroups, container.getCommand(), analysis);
                     }
+                    ResolverVisitor.resolveLanguageObject(expr, null, externalGroups, metadata);
             	}
                 
                 //second resolve the variable
                 if(statement.getType() == Statement.TYPE_DECLARE) {
                     collectDeclareVariable((DeclareStatement)statement, variables, metadata, externalGroups);
-                } else {
+                } else if (statement.getType() == Statement.TYPE_ASSIGNMENT) {
+                	AssignmentStatement assStmt = (AssignmentStatement)statement;
                     ResolverVisitor.resolveLanguageObject(assStmt.getVariable(), null, externalGroups, metadata);
                     if (statement.getType() == Statement.TYPE_ASSIGNMENT && !assStmt.getVariable().getGroupSymbol().getCanonicalName().equals(ProcedureReservedWords.VARIABLES)) {
                         throw new QueryResolverException(QueryPlugin.Util.getString("UpdateProcedureResolver.only_variables", assStmt.getVariable())); //$NON-NLS-1$
@@ -269,18 +266,15 @@
                 }
                 
                 //third ensure the type matches
-                if (assStmt.hasExpression()) {
-                    Expression expr = assStmt.getExpression();
-                    Class varType = assStmt.getVariable().getType();
-                    Class exprType = expr.getType();
-                    
-                    if (exprType == null) {
-                        throw new QueryResolverException(QueryPlugin.Util.getString("ResolveVariablesVisitor.datatype_for_the_expression_not_resolvable")); //$NON-NLS-1$
-                    }
-                    String varTypeName = DataTypeManager.getDataTypeName(varType);
-                    assStmt.setExpression(ResolverUtil.convertExpression(expr, varTypeName, metadata));                    
+                if (exprStmt.getExpression() != null) {
+	                Class<?> varType = exprStmt.getExpectedType();
+	        		Class<?> exprType = exprStmt.getExpression().getType();
+	        		if (exprType == null) {
+	        		    throw new QueryResolverException(QueryPlugin.Util.getString("ResolveVariablesVisitor.datatype_for_the_expression_not_resolvable")); //$NON-NLS-1$
+	        		}
+	        		String varTypeName = DataTypeManager.getDataTypeName(varType);
+	        		exprStmt.setExpression(ResolverUtil.convertExpression(exprStmt.getExpression(), varTypeName, metadata));          
                 }
-                
                 break;
             case Statement.TYPE_WHILE:
                 WhileStatement whileStmt = (WhileStatement) statement;

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolveVirtualGroupCriteriaVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolveVirtualGroupCriteriaVisitor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolveVirtualGroupCriteriaVisitor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -33,6 +33,7 @@
 import org.teiid.query.sql.LanguageObject;
 import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.lang.CompareCriteria;
+import org.teiid.query.sql.navigator.DeepPreOrderNavigator;
 import org.teiid.query.sql.navigator.PreOrderNavigator;
 import org.teiid.query.sql.proc.CriteriaSelector;
 import org.teiid.query.sql.proc.TranslateCriteria;
@@ -101,7 +102,7 @@
         ResolveVirtualGroupCriteriaVisitor resolveVisitor = new ResolveVirtualGroupCriteriaVisitor(virtualGroup, metadata);
         
         try {
-            PreOrderNavigator.doVisit(obj, resolveVisitor);
+            DeepPreOrderNavigator.doVisit(obj, resolveVisitor);
         } catch (TeiidRuntimeException e) {
             if (e.getChild() instanceof QueryResolverException) {
                 throw (QueryResolverException)e.getChild();

Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -115,11 +115,11 @@
 import org.teiid.query.sql.lang.PredicateCriteria.Negatable;
 import org.teiid.query.sql.navigator.PostOrderNavigator;
 import org.teiid.query.sql.navigator.PreOrderNavigator;
-import org.teiid.query.sql.proc.AssignmentStatement;
 import org.teiid.query.sql.proc.Block;
 import org.teiid.query.sql.proc.CommandStatement;
 import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
 import org.teiid.query.sql.proc.CriteriaSelector;
+import org.teiid.query.sql.proc.ExpressionStatement;
 import org.teiid.query.sql.proc.HasCriteria;
 import org.teiid.query.sql.proc.IfStatement;
 import org.teiid.query.sql.proc.LoopStatement;
@@ -344,27 +344,27 @@
 					}
 				}
 				return ifStmt;
-            case Statement.TYPE_ERROR: //treat error the same as expressions
+            case Statement.TYPE_ERROR: 
             case Statement.TYPE_DECLARE:
             case Statement.TYPE_ASSIGNMENT:
-				AssignmentStatement assStmt = (AssignmentStatement) statement;
-				// replave variables to references, these references are later
+				ExpressionStatement exprStmt = (ExpressionStatement) statement;
+				// replace variables to references, these references are later
 				// replaced in the processor with variable values
-                if (assStmt.hasExpression()) {
-    				Expression expr = assStmt.getExpression();
-    				expr = rewriteExpressionDirect(expr);
-                    assStmt.setExpression(expr);
-                } else if (assStmt.hasCommand()) {
-                    rewriteSubqueryContainer(assStmt, false);
-                    
-                    if(assStmt.getCommand().getType() == Command.TYPE_UPDATE) {
-                        Update update = (Update)assStmt.getCommand();
-                        if (update.getChangeList().isEmpty()) {
-                            assStmt.setExpression(new Constant(INTEGER_ZERO));
-                        }
-                    }
-                }
-				return assStmt;
+				Expression expr = exprStmt.getExpression();
+				if (expr != null) {
+					expr = rewriteExpressionDirect(expr);
+	                exprStmt.setExpression(expr);
+	                if (expr instanceof ScalarSubquery) {
+	                	ScalarSubquery ss = (ScalarSubquery)expr;
+	                    if(ss.getCommand().getType() == Command.TYPE_UPDATE) {
+	                        Update update = (Update)ss.getCommand();
+	                        if (update.getChangeList().isEmpty()) {
+	                            exprStmt.setExpression(new Constant(INTEGER_ZERO));
+	                        }
+	                    }
+	                }
+				}
+				return exprStmt;
 			case Statement.TYPE_COMMAND:
 				CommandStatement cmdStmt = (CommandStatement) statement;
                 rewriteSubqueryContainer(cmdStmt, false);

Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -112,9 +112,7 @@
     }    
     public void visit(HasCriteria obj) {}
     public void visit(IfStatement obj) {}
-    public void visit(RaiseErrorStatement obj) {
-        visit((AssignmentStatement)obj);
-    }
+    public void visit(RaiseErrorStatement obj) {}
     public void visit(TranslateCriteria obj) {}
     public void visit(BreakStatement obj) {}
     public void visit(ContinueStatement obj) {}

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/SetCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/SetCriteria.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/SetCriteria.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -24,8 +24,6 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
 import java.util.TreeSet;
 
 import org.teiid.core.util.EquivalenceUtil;
@@ -136,9 +134,10 @@
         if (isNegated() ^ sc.isNegated()) {
             return false;
         }
-        
-        return getValues().equals(sc.getValues()) &&
-               EquivalenceUtil.areEqual(getExpression(), sc.getExpression());
+                
+        return getValues().size() == sc.getValues().size() && 
+        	getValues().containsAll(sc.getValues()) &&
+            EquivalenceUtil.areEqual(getExpression(), sc.getExpression());
 	}
 	
 	/**

Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/DeepPreOrderNavigator.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -28,6 +28,8 @@
 import org.teiid.query.sql.lang.SubqueryCompareCriteria;
 import org.teiid.query.sql.lang.SubqueryFromClause;
 import org.teiid.query.sql.lang.SubquerySetCriteria;
+import org.teiid.query.sql.proc.CommandStatement;
+import org.teiid.query.sql.proc.LoopStatement;
 import org.teiid.query.sql.symbol.ScalarSubquery;
 
 
@@ -69,6 +71,21 @@
         visitNode(obj.getExpression());
     }
     
+    @Override
+    public void visit(CommandStatement obj) {
+    	visitVisitor(obj);
+    	visitNode(obj.getCommand());
+        visitVisitor(obj);
+    }
+    
+    @Override
+    public void visit(LoopStatement obj) {
+    	visitVisitor(obj);
+    	visitNode(obj.getCommand());
+        visitNode(obj.getBlock());
+        visitVisitor(obj);
+    }
+    
     public static void doVisit(LanguageObject object, LanguageVisitor visitor) {
         DeepPreOrderNavigator nav = new DeepPreOrderNavigator(visitor);
         object.acceptVisitor(nav);

Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -156,7 +156,7 @@
     public void visit(AssignmentStatement obj) {
         preVisitVisitor(obj);
         visitNode(obj.getVariable());
-        visitNode(obj.getValue());
+        visitNode(obj.getExpression());
         postVisitVisitor(obj);
     }
     public void visit(BatchedUpdateCommand obj) {
@@ -192,7 +192,6 @@
     }
     public void visit(CommandStatement obj) {
         preVisitVisitor(obj);
-        visitNode(obj.getCommand());
         postVisitVisitor(obj);
     }
     public void visit(CompareCriteria obj) {
@@ -227,7 +226,7 @@
     public void visit(DeclareStatement obj) {
         preVisitVisitor(obj);
         visitNode(obj.getVariable());
-        visitNode(obj.getValue());
+        visitNode(obj.getExpression());
         postVisitVisitor(obj);
     }
     public void visit(Delete obj) {
@@ -344,7 +343,6 @@
     }
     public void visit(LoopStatement obj) {
         preVisitVisitor(obj);
-        visitNode(obj.getCommand());
         visitNode(obj.getBlock());
         postVisitVisitor(obj);
     }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/AssignmentStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/AssignmentStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/AssignmentStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -24,13 +24,11 @@
 
 import org.teiid.core.util.EquivalenceUtil;
 import org.teiid.core.util.HashCodeUtil;
-import org.teiid.query.sql.*;
+import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.lang.Command;
-import org.teiid.query.sql.lang.SubqueryContainer;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.ScalarSubquery;
-import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 
 /**
@@ -39,12 +37,12 @@
  * statement holds references to the variable and it's value which could be an 
  * <code>Expression</code> or a <code>Command</code>.</p>
  */
-public class AssignmentStatement extends Statement implements SubqueryContainer{
+public class AssignmentStatement extends Statement implements ExpressionStatement {
 
 	// the variable to which a value is assigned
 	private ElementSymbol variable;
 	    
-    private LanguageObject value;
+    private Expression value;
 
 	/**
 	 * Constructor for AssignmentStatement.
@@ -53,53 +51,40 @@
 		super();
 	}
 	
-    public AssignmentStatement(ElementSymbol variable, LanguageObject value) {
+	public AssignmentStatement(ElementSymbol variable, Command value) {
         this.variable = variable;
-        if (value instanceof ScalarSubquery) {
-			ScalarSubquery scalarSubquery = (ScalarSubquery) value;
-			value = scalarSubquery.getCommand();			
-		}
+        this.value = new ScalarSubquery(value);        
+    }
+	
+    public AssignmentStatement(ElementSymbol variable, Expression value) {
+        this.variable = variable;
         this.value = value;        
     }
+ 
+    /**
+     * @see #getExpression()
+     */
+    @Deprecated
+    public Expression getValue() {
+		return value;
+	}
 
-    public boolean hasCommand() {
-        return value instanceof Command;
-    }
+    /**
+     * @see #setExpression(Expression)
+     */
+    @Deprecated
+    public void setValue(Expression value) {
+		this.value = value;
+	}
 
-    public Command getCommand() {
-        if (hasCommand()) {
-            return (Command)value;
-        }
-        return null;
-    }
-    
-    public void setCommand(Command command) {
-        this.value = command;
-    }
-    
-    public boolean hasExpression() {
-        return value instanceof Expression;
-    }
-
     public Expression getExpression() {
-        if (hasExpression()) {
-            return (Expression)value;
-        }
-        return null;
+    	return this.value;
     }
     
     public void setExpression(Expression expression) {
         this.value = expression;
     }
     
-    public LanguageObject getValue() {
-        return value;
-    }	
-    
-    public void setValue(LanguageObject value) {
-        this.value = value;
-    }   
-	
 	/**
 	 * Get the expression giving the value that is assigned to the variable.
 	 * @return An <code>Expression</code> with the value
@@ -138,7 +123,7 @@
 	 * @return Deep clone 
 	 */
 	public Object clone() {
-		AssignmentStatement clone = new AssignmentStatement((ElementSymbol) this.variable.clone(), (LanguageObject) this.value.clone());
+		AssignmentStatement clone = new AssignmentStatement((ElementSymbol) this.variable.clone(), (Expression) this.value.clone());
 		return clone;
 	}
 
@@ -166,7 +151,7 @@
     		// Compare the variables
     		EquivalenceUtil.areEqual(this.getVariable(), other.getVariable()) &&
             // Compare the values
-    		EquivalenceUtil.areEqual(this.getValue(), other.getValue());
+    		EquivalenceUtil.areEqual(this.getExpression(), other.getExpression());
             // Compare the values
     }
 
@@ -180,16 +165,14 @@
     	// and criteria clauses, not on the from, order by, or option clauses
     	int myHash = 0;
     	myHash = HashCodeUtil.hashCode(myHash, this.getVariable());
-    	myHash = HashCodeUtil.hashCode(myHash, this.getValue());
+    	myHash = HashCodeUtil.hashCode(myHash, this.getExpression());
 		return myHash;
 	}
+    
+    @Override
+    public Class<?> getExpectedType() {
+    	return getVariable().getType();
+    }
+    
       
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-    	return SQLStringVisitor.getSQLString(this);
-    }	
-
 } // END CLASS

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/BreakStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/BreakStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/BreakStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -25,7 +25,6 @@
 package org.teiid.query.sql.proc;
 
 import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 /**
  * <p> This class represents a break statement in the storedprocedure language.
@@ -76,11 +75,4 @@
         return 0;
     }
       
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-        return SQLStringVisitor.getSQLString(this);
-    }   
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -23,10 +23,9 @@
 package org.teiid.query.sql.proc;
 
 import org.teiid.core.util.EquivalenceUtil;
-import org.teiid.query.sql.*;
+import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.SubqueryContainer;
-import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 
 /**
@@ -121,12 +120,4 @@
     	return this.getCommand().hashCode();
 	}
       
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-    	return SQLStringVisitor.getSQLString(this);
-    }	
-
 } // END CLASS

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/ContinueStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/ContinueStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/ContinueStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -81,11 +81,4 @@
         return 0;
     }
       
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-        return SQLStringVisitor.getSQLString(this);
-    }   
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/DeclareStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/DeclareStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/DeclareStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -24,8 +24,9 @@
 
 import org.teiid.core.util.EquivalenceUtil;
 import org.teiid.core.util.HashCodeUtil;
-import org.teiid.query.sql.*;
+import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 
@@ -53,7 +54,7 @@
 	 * @param valueType The type of this variable
 	 */
 	public DeclareStatement(ElementSymbol variable, String varType) {
-		super(variable, null);
+		super(variable, (Expression)null);
         this.varType = varType;
 	}
 	
@@ -62,7 +63,7 @@
 	 * @param variable The <code>ElementSymbol</code> object that is the variable
 	 * @param valueType The type of this variable
 	 */
-	public DeclareStatement(ElementSymbol variable, String varType, LanguageObject value) {
+	public DeclareStatement(ElementSymbol variable, String varType, Expression value) {
         super(variable, value);
 		this.varType = varType;
 	}
@@ -108,7 +109,7 @@
         if (getValue() == null) {
             return new DeclareStatement((ElementSymbol)this.getVariable().clone(), this.varType);
         }
-        return new DeclareStatement((ElementSymbol)this.getVariable().clone(), this.varType, (LanguageObject)getValue().clone());
+        return new DeclareStatement((ElementSymbol)this.getVariable().clone(), this.varType, (Expression)getValue().clone());
 	}
 	
     /**

Added: trunk/engine/src/main/java/org/teiid/query/sql/proc/ExpressionStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/ExpressionStatement.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/ExpressionStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.sql.proc;
+
+import org.teiid.query.sql.symbol.Expression;
+
+public interface ExpressionStatement {
+	
+	Expression getExpression();
+	
+	void setExpression(Expression expr);
+	
+	Class<?> getExpectedType();
+
+}


Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/proc/ExpressionStatement.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/IfStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/IfStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/IfStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -24,9 +24,8 @@
 
 import org.teiid.core.util.EquivalenceUtil;
 import org.teiid.core.util.HashCodeUtil;
-import org.teiid.query.sql.*;
+import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.lang.Criteria;
-import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 
 /**
@@ -207,12 +206,4 @@
 		return myHash;
 	}
 
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-    	return SQLStringVisitor.getSQLString(this);
-    }
-
 } // END CLASS

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/LoopStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/LoopStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/LoopStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -26,9 +26,10 @@
 
 import org.teiid.core.util.EquivalenceUtil;
 import org.teiid.core.util.HashCodeUtil;
-import org.teiid.query.sql.*;
-import org.teiid.query.sql.lang.*;
-import org.teiid.query.sql.visitor.SQLStringVisitor;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.SubqueryContainer;
 
 
 /**
@@ -170,12 +171,4 @@
         return myHash;
     }
 
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-        return SQLStringVisitor.getSQLString(this);
-    }
-
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseErrorStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseErrorStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseErrorStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -22,11 +22,9 @@
 
 package org.teiid.query.sql.proc;
 
-import org.teiid.language.SQLConstants.Reserved;
+import org.teiid.core.types.DataTypeManager;
 import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
-import org.teiid.query.sql.symbol.GroupSymbol;
 
 
 /**
@@ -34,7 +32,9 @@
  * It extends the <code>Statement</code> that could part of a <code>Block</code>.  This
  * this object holds and error message.</p>
  */
-public class RaiseErrorStatement extends AssignmentStatement {
+public class RaiseErrorStatement extends Statement implements ExpressionStatement {
+	
+	private Expression expression;
 
 	/**
 	 * Constructor for RaiseErrorStatement.
@@ -48,33 +48,55 @@
 	 * @param message The error message
 	 */
 	public RaiseErrorStatement(Expression message) {
-        super(createElementSymbol(), message);
+		expression = message;
 	}
         
-    private static ElementSymbol createElementSymbol() {
-        /*
-         * The element symbol created here is just a placeholder for reusing
-         * the logic in AssignmentStatement/AssignmentInstruction.  It should not
-         * matter that it has an invalid ID or GroupSymbol.  Setting the type to
-         * String allows for the expression to be converted to String as necessary.
-         */
-        ElementSymbol result = new ElementSymbol(Reserved.ERROR);
-        result.setMetadataID(Reserved.ERROR);
-        result.setType(String.class);
-        result.setGroupSymbol(new GroupSymbol(Reserved.ERROR));
-        return result;
-    }
-    
     public void acceptVisitor(LanguageVisitor visitor) {
         visitor.visit(this);
     }
     
+    public Expression getExpression() {
+		return expression;
+	}
     
+    public void setExpression(Expression expression) {
+		this.expression = expression;
+	}
+    
     /** 
      * @see org.teiid.query.sql.proc.AssignmentStatement#getType()
      */
     public int getType() {
         return TYPE_ERROR;
     }
+
+	@Override
+	public RaiseErrorStatement clone() {
+		return new RaiseErrorStatement((Expression) this.expression.clone());
+	}
+	
+	@Override
+	public int hashCode() {
+		return expression.hashCode();
+	}
+	
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+		
+		if (!(obj instanceof RaiseErrorStatement)) {
+			return false;
+		}
+		
+		RaiseErrorStatement other = (RaiseErrorStatement)obj;
+		
+		return other.expression.equals(this.expression);
+	}
+	
+	@Override
+	public Class<?> getExpectedType() {
+		return DataTypeManager.DefaultDataClasses.STRING;
+	}
     
 } // END CLASS
\ No newline at end of file

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/Statement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/Statement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/Statement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -23,6 +23,7 @@
 package org.teiid.query.sql.proc;
 
 import org.teiid.query.sql.*;
+import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 /**
  * <p> This class represents the a statement in the stored procedure language.
@@ -96,4 +97,9 @@
 	 * @return Deep clone 
 	 */
 	public abstract Object clone();
+	
+	@Override
+	public String toString() {
+		return SQLStringVisitor.getSQLString(this);
+	}
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/WhileStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/WhileStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/WhileStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -28,7 +28,6 @@
 import org.teiid.core.util.HashCodeUtil;
 import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.lang.Criteria;
-import org.teiid.query.sql.visitor.SQLStringVisitor;
 
 
 /**
@@ -154,12 +153,4 @@
         return myHash;
     }
 
-    /**
-     * Returns a string representation of an instance of this class.
-     * @return String representation of object
-     */
-    public String toString() {
-        return SQLStringVisitor.getSQLString(this);
-    }
-
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/ScalarSubquery.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/ScalarSubquery.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/ScalarSubquery.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -87,9 +87,9 @@
     /**
      * @see org.teiid.query.sql.symbol.Expression#getType()
      */
-    public Class getType() {
+    public Class<?> getType() {
         if (this.type == null){
-            Expression symbol = (Expression)this.command.getProjectedSymbols().iterator().next();
+            Expression symbol = this.command.getProjectedSymbols().iterator().next();
             this.type = symbol.getType();
         }
         //may still be null if this.command wasn't resolved
@@ -100,7 +100,7 @@
      * Set type of ScalarSubquery
      * @param type New type
      */
-    public void setType(Class type) {
+    public void setType(Class<?> type) {
         this.type = type;
     }
 

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/CommandCollectorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/CommandCollectorVisitor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/CommandCollectorVisitor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -36,7 +36,6 @@
 import org.teiid.query.sql.lang.SubqueryFromClause;
 import org.teiid.query.sql.lang.SubquerySetCriteria;
 import org.teiid.query.sql.navigator.PreOrderNavigator;
-import org.teiid.query.sql.proc.AssignmentStatement;
 import org.teiid.query.sql.proc.CommandStatement;
 import org.teiid.query.sql.proc.LoopStatement;
 import org.teiid.query.sql.symbol.ScalarSubquery;
@@ -110,17 +109,6 @@
      * called directly.
      * @param obj Language object
      */
-    public void visit(AssignmentStatement obj) {
-    	if(obj.hasCommand()) {
-	        this.commands.add(obj.getCommand());
-    	}
-    }
-    
-    /**
-     * Visit a language object and collect symbols.  This method should <b>NOT</b> be 
-     * called directly.
-     * @param obj Language object
-     */
     public void visit(LoopStatement obj) {
         this.commands.add(obj.getCommand());
     }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -384,9 +384,7 @@
      * @since 5.0
      */
     public void visit(AssignmentStatement obj) {
-        if (obj.hasExpression()) {
-            obj.setExpression(replaceExpression(obj.getExpression()));
-        }
+        obj.setExpression(replaceExpression(obj.getExpression()));
     }
     
     /** 

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -41,7 +41,6 @@
 import org.teiid.query.sql.lang.AtomicCriteria;
 import org.teiid.query.sql.lang.BetweenCriteria;
 import org.teiid.query.sql.lang.CacheHint;
-import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.CompareCriteria;
 import org.teiid.query.sql.lang.CompoundCriteria;
 import org.teiid.query.sql.lang.Create;
@@ -1420,11 +1419,19 @@
         parts.add(registerNode(obj.getVariable()));
         if (obj.getValue() != null) {
             parts.add(" = "); //$NON-NLS-1$
-            parts.add(registerNode(obj.getValue()));
+            addStatementArgument(obj.getExpression());
         }
 		parts.add(";"); //$NON-NLS-1$
     }
 
+	private void addStatementArgument(Expression expr) {
+		if (expr instanceof ScalarSubquery) {
+			parts.add(registerNode(((ScalarSubquery)expr).getCommand()));
+		} else {
+			parts.add(registerNode(expr));
+		}
+	}
+
     public void visit(IfStatement obj) {
         parts.add(IF);
         parts.add("("); //$NON-NLS-1$
@@ -1534,13 +1541,10 @@
     }
 
     public void visit(RaiseErrorStatement obj) {
-        Object parts[] = new Object[4];
-
-        parts[0] = ERROR;
-        parts[1] = SPACE;
-        parts[2] = registerNode(obj.getExpression());
-        parts[3] = ";"; //$NON-NLS-1$
-        replaceStringParts(parts);
+        parts.add(ERROR);
+        parts.add(SPACE);
+        addStatementArgument(obj.getExpression());
+        parts.add(";"); //$NON-NLS-1$
     }
 
     public void visit(BreakStatement obj) {

Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -106,6 +106,7 @@
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.sql.symbol.QueryString;
 import org.teiid.query.sql.symbol.Reference;
+import org.teiid.query.sql.symbol.ScalarSubquery;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
 import org.teiid.query.sql.symbol.XMLAttributes;
 import org.teiid.query.sql.symbol.XMLElement;
@@ -152,10 +153,13 @@
     // update procedure being validated
     private CreateUpdateProcedureCommand updateProc;
     
+    public void setUpdateProc(CreateUpdateProcedureCommand updateProc) {
+		this.updateProc = updateProc;
+	}
+    
     public void reset() {
         super.reset();
         this.isXML = false;
-        this.updateProc = null;
     }
 
     // ############### Visitor methods for language objects ##################
@@ -369,22 +373,17 @@
 			handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0012, ProcedureReservedWords.INPUTS, ProcedureReservedWords.CHANGING), obj);
 		}
 
-		if(obj.hasCommand()) {
-	        Collection projSymbols = obj.getCommand().getProjectedSymbols();
+    }
+    
+    @Override
+    public void visit(ScalarSubquery obj) {
+        Collection<SingleElementSymbol> projSymbols = obj.getCommand().getProjectedSymbols();
 
-			//The command execution should result is a value that is assigned to the variable
-			// there cannot be more than one column in its results
-			if(projSymbols.size() != 1) {
-				handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0013), obj);
-			} else {
-				SingleElementSymbol value = (SingleElementSymbol) projSymbols.iterator().next();
-                Class valueType = value.getType();
-				Class varType = variable.getType();
-				if(!varType.equals(valueType)) {
-					handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.VALIDATOR_0014), obj);
-				}
-			}
-		} 
+        //Scalar subquery should have one projected symbol (query with one expression
+        //in SELECT or stored procedure execution that returns a single value).
+        if(projSymbols.size() != 1) {
+        	handleValidationError(QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0032, obj.getCommand()), obj.getCommand());
+        }
     }
 
     public void visit(CreateUpdateProcedureCommand obj) {

Modified: trunk/engine/src/main/java/org/teiid/query/validator/Validator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/Validator.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/java/org/teiid/query/validator/Validator.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -22,8 +22,8 @@
 
 package org.teiid.query.validator;
 
-import java.util.Iterator;
-import java.util.Map;
+import java.util.Iterator;
+import java.util.Map;
 
 import org.teiid.core.TeiidComponentException;
 import org.teiid.query.metadata.QueryMetadataInterface;
@@ -44,18 +44,12 @@
 
     public static final ValidatorReport validate(LanguageObject object, QueryMetadataInterface metadata, AbstractValidationVisitor visitor)
         throws TeiidComponentException {
+
+        // Execute on this command
+        executeValidation(object, metadata, visitor);
 
         // Construct combined runtime / query metadata if necessary
         if(object instanceof Command) {                        
-            Command command = (Command) object;
-            // do not validate subcommands seperatly if it is an update procedure
-            int cmdType = command.getType();
-            if(cmdType == Command.TYPE_UPDATE_PROCEDURE) {
-            	// Execute on this command
-		        executeValidation(command, metadata, visitor);
-            	return visitor.getReport();           	
-            }
-            
             // Recursively validate subcommands
             Iterator iter = CommandCollectorVisitor.getCommands((Command)object).iterator();
             while(iter.hasNext()) {
@@ -63,9 +57,6 @@
                 validate(subCommand, metadata, visitor);
             }
         }
-
-        // Execute on this command
-        executeValidation(object, metadata, visitor);
         
         // Otherwise, return a report
         return visitor.getReport();

Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2010-08-08 16:21:55 UTC (rev 2428)
@@ -819,7 +819,7 @@
     String var = null;    
     Constant type = null;  
     ElementSymbol variableID = null;
-    LanguageObject value = null;
+    Expression value = null;
 }
 {
     <DECLARE>
@@ -844,7 +844,7 @@
  */
 AssignmentStatement assignStatement(ParseInfo info) :
 {
-    LanguageObject value = null;
+    Expression value = null;
     String var = null;
     ElementSymbol elementID = null;
 }
@@ -868,7 +868,7 @@
  * arbitrarily deeply in parentheses.
  * @throws ParseException if parsing failed
  */
-LanguageObject assignStatementOperand(ParseInfo info) :
+Expression assignStatementOperand(ParseInfo info) :
 {
     LanguageObject value = null;
 }
@@ -884,7 +884,10 @@
     ) 
         
     {   
-        return value;
+    	if (value instanceof Expression) {
+    		return (Expression)value;
+    	}
+        return new ScalarSubquery((Command)value);
     }    
 }
 

Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -3599,7 +3599,7 @@
     @Test public void testDeclareStatementWithAssignment1() throws Exception {
         ElementSymbol a = new ElementSymbol("a"); //$NON-NLS-1$
         String type = new String("string"); //$NON-NLS-1$
-        DeclareStatement stmt = new DeclareStatement(a, type, sampleQuery());
+        DeclareStatement stmt = new DeclareStatement(a, type, new ScalarSubquery(sampleQuery()));
     
         helpStmtTest("DECLARE string a = SELECT a1 FROM g WHERE a2 = 5;","DECLARE string a = SELECT a1 FROM g WHERE a2 = 5;", stmt); //$NON-NLS-1$ //$NON-NLS-2$
     }

Modified: trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -30,6 +30,7 @@
 
 import org.junit.Test;
 import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryProcessingException;
 import org.teiid.api.exception.query.QueryValidatorException;
 import org.teiid.client.metadata.ParameterInfo;
 import org.teiid.core.TeiidComponentException;
@@ -1296,8 +1297,6 @@
         procedure.append("SELECT VARIABLES.e2_total;\n"); //$NON-NLS-1$
         procedure.append("END"); //$NON-NLS-1$
         
-        
-        
         QueryNode sq2n1 = new QueryNode("pm1.sq1", procedure.toString()); //$NON-NLS-1$ 
         FakeMetadataObject sq1 = FakeMetadataFactory.createVirtualProcedure("pm1.sq1", pm1, Arrays.asList(new FakeMetadataObject[] { rs2p1 }), sq2n1);  //$NON-NLS-1$
 
@@ -1400,7 +1399,36 @@
         };        
         helpTestProcess(plan, expected, dataMgr, metadata);
     }
+    
+    @Test public void testDynamicCommandValidationFails() throws Exception {
+        FakeMetadataFacade metadata = FakeMetadataFactory.example1();
+        
+        FakeMetadataObject pm1 = metadata.getStore().findObject("pm1",FakeMetadataObject.MODEL); //$NON-NLS-1$
+        
+        FakeMetadataObject rs2 = FakeMetadataFactory.createResultSet("pm1.rs2", pm1, new String[] { "e1", "e2" }, new String[] { DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.INTEGER }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        FakeMetadataObject rs2p1 = FakeMetadataFactory.createParameter("ret", 1, ParameterInfo.RESULT_SET, DataTypeManager.DefaultDataTypes.OBJECT, rs2);  //$NON-NLS-1$
+        FakeMetadataObject rs2p2 = FakeMetadataFactory.createParameter("in", 2, ParameterInfo.IN, DataTypeManager.DefaultDataTypes.STRING, null);  //$NON-NLS-1$
+        QueryNode sq2n1 = new QueryNode("pm1.sq2", "CREATE VIRTUAL PROCEDURE BEGIN\n" //$NON-NLS-1$ //$NON-NLS-2$
+                                        + "declare object VARIABLES.x; execute string 'SELECT xmlelement(name elem, x)'; select 1; END"); //$NON-NLS-1$ 
+        FakeMetadataObject sq2 = FakeMetadataFactory.createVirtualProcedure("pm1.sq2", pm1, Arrays.asList(new FakeMetadataObject[] { rs2p1, rs2p2 }), sq2n1);  //$NON-NLS-1$
 
+        metadata.getStore().addObject(rs2);
+        metadata.getStore().addObject(sq2);
+        
+        String userUpdateStr = "EXEC pm1.sq2('First')"; //$NON-NLS-1$
+        
+        FakeDataManager dataMgr = exampleDataManager(metadata);
+
+        ProcessorPlan plan = getProcedurePlan(userUpdateStr, metadata);
+         
+        try {
+        	helpTestProcess(plan, null, dataMgr, metadata);
+        	fail("exception expected");
+        } catch (QueryProcessingException e) {
+        	assertTrue(e.getCause() instanceof QueryValidatorException);
+        }
+    }
+
     @Test public void testDynamicCommandWithSingleSelect() throws Exception {
     	//Test select of a single value in a DynamicCommand
         FakeMetadataFacade metadata = FakeMetadataFactory.example1();

Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -41,6 +41,7 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryParserException;
 import org.teiid.api.exception.query.QueryResolverException;
 import org.teiid.client.metadata.ParameterInfo;
 import org.teiid.core.TeiidComponentException;
@@ -2230,12 +2231,7 @@
 
         String userUpdateStr = "UPDATE vm1.g1 SET e2=40"; //$NON-NLS-1$
         
-        FakeMetadataFacade metadata = FakeMetadataFactory.exampleUpdateProc(FakeMetadataObject.Props.UPDATE_PROCEDURE, procedure);
-
-        ProcedureContainer userCommand = (ProcedureContainer)QueryParser.getQueryParser().parseCommand(userUpdateStr);
-        QueryResolver.resolveCommand(userCommand, metadata);
-        
-        Command command = QueryResolver.expandCommand(userCommand, metadata, AnalysisRecord.createNonRecordingRecord());
+        Command command = helpResolveUpdateProcedure(procedure, userUpdateStr);
         assertEquals("CREATE PROCEDURE\nBEGIN\nDECLARE integer var1;\nROWS_UPDATED = SELECT pm1.g1.e2 FROM pm1.g1 WHERE e2 = INPUTS.e2;\nEND", command.toString());
     }
     
@@ -2644,10 +2640,6 @@
         helpResolveException(sql, "Cannot create group \'temp_table\' with multiple columns named \'column1\'"); //$NON-NLS-1$
     }
     
-    @Test public void testValidateScalarSubqueryTooManyColumns() {        
-        helpResolveException("SELECT e2, (SELECT e1, e2 FROM pm1.g1 WHERE e2 = '3') FROM pm1.g2", "There must be exactly one projected symbol of the subquery: (SELECT e1, e2 FROM pm1.g1 WHERE e2 = '3')"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
     @Test public void testXMLQuery4() {
         helpResolveException("SELECT * FROM xmltest.doc1 group by a2", "Queries against XML documents can not have a GROUP By clause"); //$NON-NLS-1$ //$NON-NLS-2$
     }
@@ -2990,4 +2982,45 @@
     	helpResolveException("select querystring(xmlparse(document '<a/>'))");
     }
     
+	// validating AssignmentStatement, ROWS_UPDATED element assigned
+    @Test(expected=QueryResolverException.class) public void testCreateUpdateProcedure9() throws Exception {
+        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 + "ROWS_UPDATED = Select pm1.g1.e1 from pm1.g1;\n"; //$NON-NLS-1$
+        procedure = procedure + "ROWS_UPDATED =0;\n";         //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userUpdateStr = "UPDATE vm1.g1 SET e1='x'"; //$NON-NLS-1$
+        
+        helpResolveUpdateProcedure(procedure, userUpdateStr);
+    }
+
+	CreateUpdateProcedureCommand helpResolveUpdateProcedure(String procedure,
+			String userUpdateStr) throws QueryParserException,
+			QueryResolverException, TeiidComponentException,
+			QueryMetadataException {
+		FakeMetadataFacade metadata = FakeMetadataFactory.exampleUpdateProc(FakeMetadataObject.Props.UPDATE_PROCEDURE, procedure);
+
+        ProcedureContainer userCommand = (ProcedureContainer)QueryParser.getQueryParser().parseCommand(userUpdateStr);
+        QueryResolver.resolveCommand(userCommand, metadata);
+        
+        return (CreateUpdateProcedureCommand)QueryResolver.expandCommand(userCommand, metadata, AnalysisRecord.createNonRecordingRecord());
+	}
+    
+	// validating AssignmentStatement, variable type and assigned type 
+	// do not match
+    @Test(expected=QueryResolverException.class) public void testCreateUpdateProcedure10() throws Exception {
+        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 + "var1 = Select pm1.g1.e1 from pm1.g1;\n"; //$NON-NLS-1$
+        procedure = procedure + "ROWS_UPDATED =0;\n";         //$NON-NLS-1$
+        procedure = procedure + "END\n"; //$NON-NLS-1$
+
+        String userUpdateStr = "UPDATE vm1.g1 SET e1='x'"; //$NON-NLS-1$
+        
+		helpResolveUpdateProcedure(procedure, userUpdateStr);
+    }
+    
 }
\ No newline at end of file

Modified: trunk/engine/src/test/java/org/teiid/query/sql/lang/TestSetCriteria.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/lang/TestSetCriteria.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/sql/lang/TestSetCriteria.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -95,23 +95,6 @@
 		assertTrue("Equivalent set criteria don't compare as equal: " + c1 + ", " + c2, c1.equals(c2));				 //$NON-NLS-1$ //$NON-NLS-2$
 	}
 
-	public void testEquals3() {   
-	    SetCriteria c1 = new SetCriteria();
-	    c1.setExpression(new ElementSymbol("e1")); //$NON-NLS-1$
-		List vals1 = new ArrayList();
-		vals1.add(new Constant("a")); //$NON-NLS-1$
-		vals1.add(new Constant("a")); //$NON-NLS-1$
-		c1.setValues(vals1);
-		
-	    SetCriteria c2 = new SetCriteria();
-	    c2.setExpression(new ElementSymbol("e1")); //$NON-NLS-1$
-		List vals2 = new ArrayList();
-		vals2.add(new Constant("a")); //$NON-NLS-1$
-		c2.setValues(vals2);
-		
-		assertTrue("Equivalent set criteria don't compare as equal: " + c1 + ", " + c2, c1.equals(c2));				 //$NON-NLS-1$ //$NON-NLS-2$
-	}
-
 	public void testSelfEquivalence(){
 		Object s1 = sample1();
 		int equals = 0;

Modified: trunk/engine/src/test/java/org/teiid/query/sql/proc/TestAssignmentStatement.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/proc/TestAssignmentStatement.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/sql/proc/TestAssignmentStatement.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -34,6 +34,7 @@
 import org.teiid.query.sql.symbol.Constant;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.ScalarSubquery;
 
 import junit.framework.TestCase;
 
@@ -79,7 +80,7 @@
 	public void testGetCommand() throws Exception {
 		AssignmentStatement s2 = sample2();
 		Query query = (Query) QueryParser.getQueryParser().parseCommand("Select x from y"); //$NON-NLS-1$
-		assertEquals("Didn't get the same parts ", s2.getCommand(), query); //$NON-NLS-1$
+		assertEquals("Didn't get the same parts ", ((ScalarSubquery)s2.getExpression()).getCommand(), query); //$NON-NLS-1$
 	}
 	
 	public void testSelfEquivalence(){

Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -352,8 +352,13 @@
         
         createKey("pk", vGroup3, vElements3.subList(0, 1));
 
+        QueryNode vTrans4 = new QueryNode("VGroup4", "/*+ cache(ttl:100) */ SELECT x FROM matsrc");         //$NON-NLS-1$ //$NON-NLS-2$
+        Table vGroup4 = createVirtualGroup("VGroup4", virtModel, vTrans4); //$NON-NLS-1$
+        vGroup4.setMaterialized(true);
+        createElements(vGroup4,
+                                      new String[] { "x" }, //$NON-NLS-1$
+                                      new String[] { DataTypeManager.DefaultDataTypes.STRING});
 
-
         return createTransformationMetadata(metadataStore, "");
     }
     

Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2010-08-07 12:55:23 UTC (rev 2427)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2010-08-08 16:21:55 UTC (rev 2428)
@@ -1127,37 +1127,6 @@
 									 FakeMetadataObject.Props.UPDATE_PROCEDURE);
     }
 
-	// validating AssignmentStatement, ROWS_UPDATED element assigned
-    @Test public void testCreateUpdateProcedure9() {
-        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 + "ROWS_UPDATED = Select pm1.g1.e1 from pm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "ROWS_UPDATED =0;\n";         //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userUpdateStr = "UPDATE vm1.g1 SET e1='x'"; //$NON-NLS-1$
-        
-		helpFailProcedure(procedure, userUpdateStr,
-									 FakeMetadataObject.Props.UPDATE_PROCEDURE);
-    }
-    
-	// validating AssignmentStatement, variable type and assigned type 
-	// do not match
-    @Test public void testCreateUpdateProcedure10() {
-        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 + "var1 = Select pm1.g1.e1 from pm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "ROWS_UPDATED =0;\n";         //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-
-        String userUpdateStr = "UPDATE vm1.g1 SET e1='x'"; //$NON-NLS-1$
-        
-		helpFailProcedure(procedure, userUpdateStr,
-									 FakeMetadataObject.Props.UPDATE_PROCEDURE);
-    }
-
 	// validating AssignmentStatement, more than one project symbol on the
 	// command
     @Test public void testCreateUpdateProcedure11() {
@@ -2056,5 +2025,9 @@
     @Test public void testValidateStatAgg() {        
         helpValidate("SELECT stddev_pop(distinct e2) from pm1.g1", new String[] {"STDDEV_POP(DISTINCT e2)"}, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
 	}
+    
+    @Test public void testValidateScalarSubqueryTooManyColumns() {        
+        helpValidate("SELECT e2, (SELECT e1, e2 FROM pm1.g1 WHERE e2 = '3') FROM pm1.g2", new String[] {"SELECT e1, e2 FROM pm1.g1 WHERE e2 = '3'"}, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
 
 }



More information about the teiid-commits mailing list