Author: gates
Date: Thu Jun 19 16:04:07 2008
New Revision: 669739

URL: http://svn.apache.org/viewvc?rev=669739&view=rev
Log:
PIG-158 Santhosh's patch to handle casting to tuples and bags and type checking 
on tuples and bags.


Modified:
    incubator/pig/branches/types/build.xml
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/ExpressionOperator.java
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOCast.java
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOConst.java
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOPrinter.java
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/parser/QueryParser.jjt
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java
    
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/validators/TypeCheckingVisitor.java
    
incubator/pig/branches/types/test/org/apache/pig/test/TestLogicalPlanBuilder.java
    
incubator/pig/branches/types/test/org/apache/pig/test/TestTypeCheckingValidator.java

Modified: incubator/pig/branches/types/build.xml
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/build.xml?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- incubator/pig/branches/types/build.xml (original)
+++ incubator/pig/branches/types/build.xml Thu Jun 19 16:04:07 2008
@@ -279,7 +279,6 @@
                     <include name="**/*Test*.java" />
                     <!-- Excluced because they are end-to-end, don't work yet. 
 -->
                     <exclude name="**/TestAlgebraicEval.java" />
-                    <exclude name="**/TestCombiner.java" />
                     <exclude name="**/TestCompressedFiles.java" />
                     <exclude name="**/TestEvalPipeline.java" />
                     <exclude name="**/TestFilterOpNumeric.java" />

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/ExpressionOperator.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/ExpressionOperator.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/ExpressionOperator.java
 (original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/ExpressionOperator.java
 Thu Jun 19 16:04:07 2008
@@ -114,6 +114,15 @@
                                throw new FrontendException(pe.getMessage());
                        }
         }
+        mIsFieldSchemaComputed = true;
+    }
+
+    void setFieldSchemaComputed(boolean b) {
+        mIsFieldSchemaComputed = b;
+    }
+
+    boolean getFieldSchemaComputed() {
+        return mIsFieldSchemaComputed;
     }
 
 }

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOCast.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOCast.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOCast.java 
(original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOCast.java 
Thu Jun 19 16:04:07 2008
@@ -22,6 +22,7 @@
 import org.apache.pig.impl.plan.PlanVisitor;
 import org.apache.pig.impl.plan.VisitorException;
 import org.apache.pig.impl.logicalLayer.schema.Schema;
+import org.apache.pig.data.DataType;
 
 public class LOCast extends ExpressionOperator {
 
@@ -64,6 +65,12 @@
 
     @Override
     public Schema.FieldSchema getFieldSchema() {
+        if(!mIsFieldSchemaComputed && (null == mFieldSchema)) {
+            if(DataType.isAtomic(mType)) {
+                mFieldSchema = new Schema.FieldSchema(null, mType);
+                mIsFieldSchemaComputed = true;
+            }
+        }
         return mFieldSchema;
     }
 

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOConst.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOConst.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOConst.java 
(original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOConst.java 
Thu Jun 19 16:04:07 2008
@@ -22,6 +22,7 @@
 import org.apache.pig.impl.plan.PlanVisitor;
 import org.apache.pig.impl.plan.VisitorException;
 import org.apache.pig.impl.logicalLayer.schema.Schema;
+import org.apache.pig.data.DataType;
 
 public class LOConst extends ExpressionOperator {
 
@@ -60,6 +61,12 @@
 
     @Override
     public Schema.FieldSchema getFieldSchema() {
+        if(!mIsFieldSchemaComputed && (null == mFieldSchema)) {
+            if(DataType.isAtomic(mType)) {
+                mFieldSchema = new Schema.FieldSchema(null, mType);
+                mIsFieldSchemaComputed = true;
+            }
+        }
         return mFieldSchema;
     }
 

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOPrinter.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOPrinter.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOPrinter.java
 (original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/LOPrinter.java
 Thu Jun 19 16:04:07 2008
@@ -153,13 +153,6 @@
         }
         
         List<LogicalOperator> predecessors = mPlan.getPredecessors(node);
-        if(node instanceof LOProject) {
-            System.err.println("LOProject " + node + " predecessors: " + 
predecessors + " in plan " + mPlan);
-            System.err.println("mPlan size: " + mPlan.size());
-        } else if(node instanceof LOSort) {
-            System.err.println("LOSort : " + node + " predecessors: " + 
predecessors + " in plan " + mPlan);
-            System.err.println("mPlan size: " + mPlan.size());
-        }
         
         if (predecessors == null)
             return sb.toString();

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/parser/QueryParser.jjt
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/parser/QueryParser.jjt?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/parser/QueryParser.jjt
 (original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/parser/QueryParser.jjt
 Thu Jun 19 16:04:07 2008
@@ -1633,16 +1633,18 @@
 ExpressionOperator CastExpr(Schema over, Map<String, LogicalOperator> 
specs,LogicalPlan lp,LogicalOperator input) :
 {
     byte type = DataType.BYTEARRAY;
+    Schema.FieldSchema fs = null;
     ExpressionOperator cast;
     ExpressionOperator exprOp;
     boolean castRequired = false;
     log.trace("Entering Cast");
 }
 {
-    [LOOKAHEAD(2)"(" type = Type() {castRequired = true;}")"] exprOp = 
UnaryExpr(over, specs, lp, input)
+    [LOOKAHEAD(2)"(" fs = TypeFieldSchema() {castRequired = true;}")"] exprOp 
= UnaryExpr(over, specs, lp, input)
     {
         if(castRequired) {
-            cast = new LOCast(lp, new OperatorKey(scope, getNextId()), exprOp, 
type);
+            cast = new LOCast(lp, new OperatorKey(scope, getNextId()), exprOp, 
fs.type);
+            cast.setFieldSchema(fs);
             lp.add(cast);
                    log.debug("Added operator " + cast.getClass().getName() + " 
" + cast + " to logical plan " + lp);
             lp.connect(exprOp, cast);
@@ -2149,6 +2151,130 @@
 }
 
 
+Schema.FieldSchema TypeFieldSchema() : 
+{
+       Token t1; 
+       Schema item = null; 
+       Schema.FieldSchema fs = null; 
+       log.trace("Entering TypeFieldSchema");
+}
+{
+       (
+       LOOKAHEAD(TypeSchemaTuple()) fs = TypeSchemaTuple()
+|      LOOKAHEAD(TypeSchemaBag()) fs = TypeSchemaBag()
+|      LOOKAHEAD(TypeSchemaMap()) fs = TypeSchemaMap()
+|      LOOKAHEAD(TypeAtomSchema()) fs = TypeAtomSchema()
+       )
+       //{log.debug("Printing Aliases"); 
item.printAliases();log.trace("Exiting Schema");return item;}
+       {log.trace("Exiting TypeFieldSchema");return fs;}
+}
+
+Schema.FieldSchema TypeAtomSchema() : 
+{
+       Token t1 = null;
+       byte type = DataType.BYTEARRAY;
+       Schema.FieldSchema fs;
+       log.trace("Entering TypeAtomSchema");
+}
+{
+       //(  ( [t1 = <IDENTIFIER> ":"] type = BasicType() )
+       (  ( type = BasicType() )
+               { 
+                       if(null != t1) {
+                               log.debug("AtomSchema: " + t1.image);
+                               fs = new Schema.FieldSchema(t1.image, type); 
+                       } else {
+                               fs = new Schema.FieldSchema(null, type); 
+                       }
+                       
+                       log.trace("Exiting TypeAtomSchema");
+                       return fs;
+               } 
+       )
+}
+
+Schema.FieldSchema TypeSchemaMap() :
+{
+       Token t1 = null; 
+       Schema.FieldSchema fs;
+       log.trace("Entering TypeSchemaMap");
+}
+{
+       ( <MAP> "[" "]")
+       {
+               if (null != t1) {
+                       log.debug("MAP alias " + t1.image);
+                       fs = new Schema.FieldSchema(t1.image, DataType.MAP);
+               } else {
+                       fs = new Schema.FieldSchema(null, DataType.MAP);
+               }
+               log.trace("Exiting TypeSchemaMap");
+               return fs;
+       } 
+}
+
+Schema.FieldSchema TypeSchemaTuple() : 
+{
+       Token t1 = null; 
+       Schema s;
+       Schema.FieldSchema fs;
+       log.trace("Entering TypeSchemaTuple");
+}
+{ 
+       ( <TUPLE> "(" s = TypeTupleSchema() ")") 
+       {
+               if (null != t1) {
+                       log.debug("TUPLE alias " + t1.image);
+                       fs = new Schema.FieldSchema(t1.image, s, 
DataType.TUPLE);
+               } else {
+                       fs = new Schema.FieldSchema(null, s, DataType.TUPLE);
+               }
+               log.trace("Exiting TypeSchemaTuple");
+               return fs;
+       } 
+}
+
+Schema.FieldSchema TypeSchemaBag() : 
+{
+       Token t1 = null; 
+       Schema s;
+       Schema.FieldSchema fs;
+       log.trace("Entering TypeSchemaBag");
+}
+{ 
+       ( <BAG> "{" (fs = TypeSchemaTuple() | {} {fs = new 
Schema.FieldSchema(null, new Schema());}) "}" ) 
+       {
+        s = new Schema(fs);
+               if (null != t1) {
+                       log.debug("BAG alias " + t1.image);
+                       fs = new Schema.FieldSchema(t1.image, s, DataType.BAG);
+               } else {
+                       fs = new Schema.FieldSchema(null, s, DataType.BAG);
+               }
+               log.trace("Exiting TypeSchemaBag");
+               return fs;
+       } 
+}
+
+
+Schema TypeTupleSchema() : 
+{
+       Schema item = null; 
+       Schema list = new Schema(); 
+       Schema.FieldSchema fs = null;
+       log.trace("Entering TypeTupleSchema");
+}
+{
+       (       
+       (       
+               fs = TypeFieldSchema() {log.debug("Adding " + fs.alias + " to 
the list: " + list);list.add(fs);} 
+               ( "," fs = TypeFieldSchema() {log.debug("Adding " + fs.alias + 
" to the list: " + list);list.add(fs);})* 
+       )
+|              {}
+       )
+       {log.debug("Printing Aliases in TypeTupleSchema"); 
list.printAliases();log.trace("Exiting TypeTupleSchema");return list;}
+}
+
 // These the simple non-terminals that are shared across many
 
 EvalFunc  EvalFunction() : 

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java
 (original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java
 Thu Jun 19 16:04:07 2008
@@ -133,6 +133,71 @@
                     + ( (alias==null? 0:alias.hashCode()) * 29 ) ;
         }
 
+        /**
+         * Recursively compare two schemas to check if the input schema 
+         * can be cast to the cast schema
+         * @param cast schema of the cast operator
+         * @param  input schema of the cast input
+         * @return true or falsew!
+         */
+        public static boolean castable(Schema.FieldSchema castFs, 
Schema.FieldSchema inputFs) {
+            if(castFs == null && inputFs == null) {
+                return false;
+            }
+            
+            if (castFs == null) {
+                return false ;
+            }
+    
+            if (inputFs == null) {
+                return false ;
+            }
+            byte inputType = inputFs.type;
+            byte castType = castFs.type;
+    
+            if (DataType.isSchemaType(castFs.type)) {
+                if(inputType == DataType.BYTEARRAY) {
+                    //good
+                } else if (inputType == castType) {
+                    // Don't do the comparison if both embedded schemas are
+                    // null.  That will cause Schema.equals to return false,
+                    // even though we want to view that as true.
+                    if (!(castFs.schema == null && inputFs.schema == null)) { 
+                        // compare recursively using schema
+                        if (!Schema.castable(castFs.schema, inputFs.schema)) {
+                            return false ;
+                        }
+                    }
+                } else {
+                    return false;
+                }
+            } else {
+                if (inputType == castType) {
+                    //good
+                }
+                else if (DataType.isNumberType(inputType) &&
+                    DataType.isNumberType(castType) ) {
+                    //good
+                }
+                else if (inputType == DataType.BYTEARRAY) {
+                    //good
+                }
+                else if (  ( DataType.isNumberType(inputType) || 
+                             inputType == DataType.CHARARRAY 
+                           )  &&
+                           (  (castType == DataType.CHARARRAY) ||
+                              (castType == DataType.BYTEARRAY)    
+                           ) 
+                        ) {
+                    //good
+                } else {
+                    return false;
+                }
+            }
+    
+            return true ;
+        }
+
         /***
          * Compare two field schema for equality
          * @param fschema
@@ -507,6 +572,49 @@
     }
 
     /**
+     * Recursively compare two schemas to check if the input schema 
+     * can be cast to the cast schema
+     * @param cast schema of the cast operator
+     * @param  input schema of the cast input
+     * @return true or falsew!
+     */
+    public static boolean castable(Schema cast, Schema input) {
+
+        // If both of them are null, they are castable
+        if ((cast == null) && (input == null)) {
+            return false ;
+        }
+
+        // otherwise
+        if (cast == null) {
+            return false ;
+        }
+
+        if (input == null) {
+            return false ;
+        }
+
+        if (cast.size() > input.size()) return false;
+
+        Iterator<FieldSchema> i = cast.mFields.iterator();
+        Iterator<FieldSchema> j = input.mFields.iterator();
+
+        while (i.hasNext()) {
+        //iterate only for the number of fields in cast
+
+            FieldSchema castFs = i.next() ;
+            FieldSchema inputFs = j.next() ;
+
+            // Compare recursively using field schema
+            if (!FieldSchema.castable(castFs, inputFs)) {
+                return false ;
+            }
+
+        }
+        return true;
+    }
+
+    /**
      * Recursively compare two schemas for equality
      * @param schema
      * @param other

Modified: 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/validators/TypeCheckingVisitor.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/validators/TypeCheckingVisitor.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/validators/TypeCheckingVisitor.java
 (original)
+++ 
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/validators/TypeCheckingVisitor.java
 Thu Jun 19 16:04:07 2008
@@ -1241,46 +1241,35 @@
     }
 
     /**
+     * For Basic Types:
      * 0) Casting to itself is always ok
      * 1) Casting from number to number is always ok 
      * 2) ByteArray to anything is ok
      * 3) (number or chararray) to (bytearray or chararray) is ok
+     * For Composite Types:
+     * Recursively traverse the schemas till you get a basic type
      */
     @Override
     protected void visit(LOCast cast) throws VisitorException {      
         
-        // TODO: Add support for tuple casting????
-        if (cast.getType() == DataType.TUPLE) {
-            throw new AssertionError("Tuple schema casting is not supported 
yet") ;
-        }
-        
-        byte inputType = cast.getExpression().getType() ; 
-        byte expectedType = cast.getType() ;     
-        
-        if (inputType == cast.getType()) {
-            // good
-        }
-        else if (DataType.isNumberType(inputType) &&
-            DataType.isNumberType(expectedType) ) {
-            // good
-        }
-        else if (inputType == DataType.BYTEARRAY) {
-            // good
-        }
-        else if (  ( DataType.isNumberType(inputType) || 
-                     inputType == DataType.CHARARRAY 
-                   )  &&
-                   (  (expectedType == DataType.CHARARRAY) ||
-                      (expectedType == DataType.BYTEARRAY)    
-                   ) 
-                ) {
-            // good
+        byte inputType = cast.getExpression().getType(); 
+        byte expectedType = cast.getType();
+        Schema.FieldSchema castFs;
+        Schema.FieldSchema inputFs;
+        try {
+            castFs = cast.getFieldSchema();
+            inputFs = cast.getExpression().getFieldSchema();
+        } catch(FrontendException fee) {
+            throw new VisitorException(fee.getMessage());
         }
-        else {
+        boolean castable = castable = Schema.FieldSchema.castable(castFs, 
inputFs);
+        if(!castable) {
             String msg = "Cannot cast "
                            + DataType.findTypeName(inputType)
+                           + ((DataType.isSchemaType(inputType))? " with 
schema " + inputFs : "")
                            + " to "
-                           + DataType.findTypeName(expectedType) ;
+                           + DataType.findTypeName(expectedType)
+                           + ((DataType.isSchemaType(expectedType))? " with 
schema " + castFs : "");
             msgCollector.collect(msg, MessageType.Error) ;
             throw new VisitorException(msg) ; 
         }

Modified: 
incubator/pig/branches/types/test/org/apache/pig/test/TestLogicalPlanBuilder.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/test/org/apache/pig/test/TestLogicalPlanBuilder.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/test/org/apache/pig/test/TestLogicalPlanBuilder.java
 (original)
+++ 
incubator/pig/branches/types/test/org/apache/pig/test/TestLogicalPlanBuilder.java
 Thu Jun 19 16:04:07 2008
@@ -848,8 +848,33 @@
     public void testQuery72() {
         buildPlan("split (load 'a') into x if $0 > '7', y if $0 < '7';");
         buildPlan("b = foreach x generate (int)$0;");
-        buildPlan("c = foreach y generate (bag)$1;");
+        buildPlan("c = foreach y generate (bag{})$1;");
         buildPlan("d = foreach y generate (int)($1/2);");
+        buildPlan("e = foreach y generate (bag{tuple(int, float)})($1/2);");
+        buildPlan("f = foreach x generate (tuple(int, float))($1/2);");
+        buildPlan("g = foreach x generate (tuple())($1/2);");
+        buildPlan("h = foreach x generate (chararray)($1/2);");
+        buildPlan("i = foreach x generate (bytearray)($1/2);");
+    }
+
+    @Test
+    public void testQueryFail72() {
+        buildPlan("split (load 'a') into x if $0 > '7', y if $0 < '7';");
+        try {
+            buildPlan("c = foreach y generate (bag)$1;");
+        } catch (AssertionFailedError e) {
+            assertTrue(e.getMessage().contains("Exception"));
+        }
+        try {
+            buildPlan("c = foreach y generate (bag{int, float})$1;");
+        } catch (AssertionFailedError e) {
+            assertTrue(e.getMessage().contains("Exception"));
+        }
+        try {
+            buildPlan("c = foreach y generate (tuple)$1;");
+        } catch (AssertionFailedError e) {
+            assertTrue(e.getMessage().contains("Exception"));
+        }
     }
 
     @Test
@@ -890,6 +915,7 @@
         } catch (Exception e) {
             System.err.println(e.getMessage());
         }
+        System.err.println();
     }
     
     // Helper Functions

Modified: 
incubator/pig/branches/types/test/org/apache/pig/test/TestTypeCheckingValidator.java
URL: 
http://svn.apache.org/viewvc/incubator/pig/branches/types/test/org/apache/pig/test/TestTypeCheckingValidator.java?rev=669739&r1=669738&r2=669739&view=diff
==============================================================================
--- 
incubator/pig/branches/types/test/org/apache/pig/test/TestTypeCheckingValidator.java
 (original)
+++ 
incubator/pig/branches/types/test/org/apache/pig/test/TestTypeCheckingValidator.java
 Thu Jun 19 16:04:07 2008
@@ -364,6 +364,178 @@
     }
     
     @Test
+    public void testExpressionTypeChecking8() throws Throwable {
+        LogicalPlan plan = new LogicalPlan() ;
+        
+           TupleFactory tupleFactory = TupleFactory.getInstance();
+
+           ArrayList<Object> innerObjList = new ArrayList<Object>(); 
+           ArrayList<Object> objList = new ArrayList<Object>(); 
+
+        innerObjList.add(10);
+        innerObjList.add(3);
+        innerObjList.add(7);
+        innerObjList.add(17);
+
+               Tuple innerTuple = tupleFactory.newTuple(innerObjList);
+
+        objList.add("World");
+        objList.add(42);
+        objList.add(innerTuple);
+        
+               Tuple tuple = tupleFactory.newTuple(objList);
+        
+        ArrayList<Schema.FieldSchema> innerFss = new 
ArrayList<Schema.FieldSchema>();
+        ArrayList<Schema.FieldSchema> fss = new 
ArrayList<Schema.FieldSchema>();
+        ArrayList<Schema.FieldSchema> castFss = new 
ArrayList<Schema.FieldSchema>();
+
+        Schema.FieldSchema stringFs = new Schema.FieldSchema(null, 
DataType.CHARARRAY);
+        Schema.FieldSchema intFs = new Schema.FieldSchema(null, 
DataType.INTEGER);
+
+        for(int i = 0; i < innerObjList.size(); ++i) {
+            innerFss.add(intFs);
+        }
+
+        Schema innerTupleSchema = new Schema(innerFss);
+
+        fss.add(stringFs);
+        fss.add(intFs);
+        fss.add(new Schema.FieldSchema(null, innerTupleSchema, 
DataType.TUPLE));
+
+        Schema tupleSchema = new Schema(fss);
+
+        for(int i = 0; i < 3; ++i) {
+            castFss.add(stringFs);
+        }
+
+        Schema castSchema = new Schema(castFss);
+
+
+        LOConst constant1 = new LOConst(plan, genNewOperatorKey(), innerTuple) 
;
+        constant1.setType(DataType.TUPLE) ;
+        constant1.setFieldSchema(new Schema.FieldSchema(null, 
innerTupleSchema, DataType.TUPLE));
+        LOConst constant2 =  new LOConst(plan, genNewOperatorKey(), tuple) ;
+        constant2.setType(DataType.TUPLE) ;
+        constant2.setFieldSchema(new Schema.FieldSchema(null, tupleSchema, 
DataType.TUPLE));
+        LOCast cast1 = new LOCast(plan, genNewOperatorKey(), constant1, 
DataType.TUPLE) ;
+        cast1.setFieldSchema(new FieldSchema(null, castSchema, 
DataType.TUPLE));
+        
+        LOEqual equal1 = new LOEqual(plan, genNewOperatorKey(), cast1, 
constant2) ;
+        
+        plan.add(constant1) ;
+        plan.add(constant2) ;
+        plan.add(cast1) ;
+        plan.add(equal1) ;
+              
+        plan.connect(constant1, cast1) ;
+        plan.connect(cast1, equal1) ;
+        plan.connect(constant2, equal1) ;
+                      
+        CompilationMessageCollector collector = new 
CompilationMessageCollector() ;
+        TypeCheckingValidator typeValidator = new TypeCheckingValidator() ;
+        typeValidator.validate(plan, collector) ;    
+        printMessageCollector(collector) ;
+        printTypeGraph(plan) ;
+        
+        if (collector.hasError()) {
+            throw new Exception("Error during type checking") ;
+        }   
+
+        assertEquals(DataType.BOOLEAN, equal1.getType()) ;
+        assertEquals(DataType.TUPLE, equal1.getRhsOperand().getType()) ;
+        assertEquals(DataType.TUPLE, equal1.getLhsOperand().getType()) ;
+    }
+
+    @Test
+    public void testExpressionTypeCheckingFail8() throws Throwable {
+        LogicalPlan plan = new LogicalPlan() ;
+        
+           TupleFactory tupleFactory = TupleFactory.getInstance();
+
+           ArrayList<Object> innerObjList = new ArrayList<Object>(); 
+           ArrayList<Object> objList = new ArrayList<Object>(); 
+
+        innerObjList.add("10");
+        innerObjList.add("3");
+        innerObjList.add(7);
+        innerObjList.add("17");
+
+               Tuple innerTuple = tupleFactory.newTuple(innerObjList);
+
+        objList.add("World");
+        objList.add(42);
+        objList.add(innerTuple);
+        
+               Tuple tuple = tupleFactory.newTuple(objList);
+        
+        ArrayList<Schema.FieldSchema> innerFss = new 
ArrayList<Schema.FieldSchema>();
+        ArrayList<Schema.FieldSchema> fss = new 
ArrayList<Schema.FieldSchema>();
+        ArrayList<Schema.FieldSchema> castFss = new 
ArrayList<Schema.FieldSchema>();
+
+        Schema.FieldSchema stringFs = new Schema.FieldSchema(null, 
DataType.CHARARRAY);
+        Schema.FieldSchema intFs = new Schema.FieldSchema(null, 
DataType.INTEGER);
+        Schema.FieldSchema doubleFs = new Schema.FieldSchema(null, 
DataType.DOUBLE);
+
+        innerFss.add(stringFs);
+        innerFss.add(stringFs);
+        innerFss.add(intFs);
+        innerFss.add(stringFs);
+
+        Schema innerTupleSchema = new Schema(innerFss);
+
+        fss.add(stringFs);
+        fss.add(intFs);
+        fss.add(new Schema.FieldSchema(null, innerTupleSchema, 
DataType.TUPLE));
+
+        Schema tupleSchema = new Schema(fss);
+
+        castFss.add(stringFs);
+        castFss.add(stringFs);
+        castFss.add(doubleFs);
+        castFss.add(intFs);
+
+        Schema castSchema = new Schema(castFss);
+
+
+        LOConst constant1 = new LOConst(plan, genNewOperatorKey(), innerTuple) 
;
+        constant1.setType(DataType.TUPLE) ;
+        constant1.setFieldSchema(new Schema.FieldSchema(null, 
innerTupleSchema, DataType.TUPLE));
+        LOConst constant2 =  new LOConst(plan, genNewOperatorKey(), tuple) ;
+        constant2.setType(DataType.TUPLE) ;
+        constant2.setFieldSchema(new Schema.FieldSchema(null, tupleSchema, 
DataType.TUPLE));
+        LOCast cast1 = new LOCast(plan, genNewOperatorKey(), constant1, 
DataType.TUPLE) ;
+        cast1.setFieldSchema(new FieldSchema(null, castSchema, 
DataType.TUPLE));
+        
+        LOEqual equal1 = new LOEqual(plan, genNewOperatorKey(), cast1, 
constant2) ;
+        
+        plan.add(constant1) ;
+        plan.add(constant2) ;
+        plan.add(cast1) ;
+        plan.add(equal1) ;
+              
+        plan.connect(constant1, cast1) ;
+        plan.connect(cast1, equal1) ;
+        plan.connect(constant2, equal1) ;
+                      
+        CompilationMessageCollector collector = new 
CompilationMessageCollector() ;
+        TypeCheckingValidator typeValidator = new TypeCheckingValidator() ;
+
+        try {
+            typeValidator.validate(plan, collector) ; 
+            fail("Exception expected") ;
+        } catch(PlanValidationException pve) {
+            //good
+        }
+
+        printMessageCollector(collector) ;
+        printTypeGraph(plan) ;
+        
+        if (!collector.hasError()) {
+            throw new Exception("Error expected") ;
+        }   
+    }
+
+    @Test
     public void testArithmeticOpCastInsert1() throws Throwable {
         LogicalPlan plan = new LogicalPlan() ;
         LOConst constant1 = new LOConst(plan, genNewOperatorKey(), 10) ;


Reply via email to