*/
private LOForEach insertCastForEachInBetweenIfNecessary(LogicalOperator fromOp,
LogicalOperator toOp,
Schema targetSchema)
throws VisitorException {
LogicalPlan currentPlan = mCurrentWalker.getPlan() ;
/*
// Make sure that two operators are in the same plan
if (fromOp.getPlan() != toOp.getPlan()) {
throw new AssertionError("Two operators have toOp be in the same plan") ;
}
// Mare sure that they are in the plan we're looking at
if (fromOp.getPlan() != toOp.getPlan()) {
throw new AssertionError("Cannot manipulate any other plan"
+" than the current one") ;
}
*/
// Make sure that they are adjacent and the direction
// is from "fromOp" to "toOp"
List<LogicalOperator> preList = currentPlan.getPredecessors(toOp) ;
boolean found = false ;
for(LogicalOperator tmpOp: preList) {
// compare by reference
if (tmpOp == fromOp) {
found = true ;
break ;
}
}
if (!found) {
int errCode = 1077;
String msg = "Two operators that require a cast in between are not adjacent.";
throw new TypeCheckerException(msg, errCode, PigException.INPUT);
}
// retrieve input schema to be casted
// this will be used later
Schema fromSchema = null ;
try {
fromSchema = fromOp.getSchema() ;
}
catch(FrontendException fe) {
int errCode = 1055;
String msg = "Problem while reading schema from input of " + fromOp.getClass().getSimpleName();
throw new TypeCheckerException(msg, errCode, PigException.BUG, fe);
}
// make sure the supplied targetSchema has the same number of members
// as number of output fields from "fromOp"
if (fromSchema.size() != targetSchema.size()) {
int errCode = 1078;
String msg = "Schema size mismatch for casting. Input schema size: " + fromSchema.size() + ". Target schema size: " + targetSchema.size();
throw new TypeCheckerException(msg, errCode, PigException.INPUT);
}
// Plans inside Generate. Fields that do not need casting will only
// have Project. Fields that need casting will have Project + Cast
ArrayList<LogicalPlan> generatePlans = new ArrayList<LogicalPlan>() ;
int castNeededCounter = 0 ;
for(int i=0;i < fromSchema.size(); i++) {
LogicalPlan genPlan = new LogicalPlan() ;
LOProject project = new LOProject(genPlan,
genNewOperatorKey(fromOp),
fromOp,
i) ;
project.setSentinel(true);
genPlan.add(project);
// add casting if necessary by comparing target types
// to the input schema
FieldSchema fs = null ;
try {
fs = fromSchema.getField(i) ;
}
catch(FrontendException fee) {
int errCode = 1063;
String msg = "Problem while reading"
+ " field schema from input while"
+ " inserting cast " ;
msgCollector.collect(msg, MessageType.Error) ;
throw new TypeCheckerException(msg, errCode, PigException.INPUT, fee) ;
}
// This only does "shallow checking"
byte inputFieldType ;
try {
inputFieldType = targetSchema.getField(i).type ;
}
catch (FrontendException fee) {
int errCode = 1064;
String msg = "Problem reading column " + i + " from schema: " + targetSchema;
throw new TypeCheckerException(msg, errCode, PigException.INPUT, fee) ;
}
if (inputFieldType != fs.type) {
castNeededCounter++ ;
LOCast cast = new LOCast(genPlan,
genNewOperatorKey(fromOp),
inputFieldType) ;
genPlan.add(cast) ;
try {
genPlan.connect(project, cast);
}
catch (PlanException pe) {
// This should never happen
int errCode = 2059;
String msg = "Problem with inserting cast operator for project in plan.";