in src/org/apache/pig/backend/hadoop/executionengine/physicalLayer/expressionOperators/POCast.java [1306:1809]
private Object convertWithSchema(Object obj, ResourceFieldSchema fs) throws IOException {
Object result = null;
if (fs == null) {
return obj;
}
if (obj == null) {
// handle DataType.NULL
return null;
}
switch (fs.getType()) {
case DataType.BAG:
if (obj instanceof DataBag) {
DataBag db = (DataBag)obj;
// Get inner schema of a bag
if (fs.getSchema()!=null) {
ResourceFieldSchema tupleFs = fs.getSchema().getFields()[0];
Iterator<Tuple> iter = db.iterator();
while (iter.hasNext()) {
Tuple t = iter.next();
convertWithSchema(t, tupleFs);
}
}
result = db;
} else if (obj instanceof DataByteArray) {
if (null != caster) {
result = caster.bytesToBag(((DataByteArray)obj).get(), fs);
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "bag for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
} else {
throw new ExecException("Cannot cast " + obj + " to bag.", 1120, PigException.INPUT);
}
break;
case DataType.TUPLE:
if (obj instanceof Tuple) {
try {
Tuple t = (Tuple)obj;
ResourceSchema innerSchema = fs.getSchema();
if (innerSchema==null)
return t;
if (innerSchema.getFields().length!=t.size())
return null;
int i=0;
for (ResourceFieldSchema fieldSchema : innerSchema.getFields()) {
Object field = convertWithSchema(t.get(i), fieldSchema);
t.set(i, field);
i++;
}
result = t;
} catch (Exception e) {
throw new ExecException("Cannot convert "+ obj + " to " + fs);
}
} else if (obj instanceof DataByteArray) {
if (null != caster) {
result = caster.bytesToTuple(((DataByteArray)obj).get(), fs);
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "tuple for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
} else {
throw new ExecException("Cannot cast " + obj + " to tuple.", 1120, PigException.INPUT);
}
break;
case DataType.MAP:
if (obj instanceof Map) {
if (fs!=null && fs.getSchema()!=null) {
ResourceFieldSchema innerFieldSchema = fs.getSchema().getFields()[0];
Map m = (Map)obj;
for (Object entry : m.entrySet()) {
Object newValue = convertWithSchema(((Map.Entry)entry).getValue(), innerFieldSchema);
m.put(((Map.Entry)entry).getKey(), newValue);
}
result = m;
}
else
result = obj;
} else if (obj instanceof DataByteArray) {
if (null != caster) {
result = caster.bytesToMap(((DataByteArray)obj).get(), fs);
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "tuple for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
} else {
throw new ExecException("Cannot cast " + obj + " to map.", 1120, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToBoolean(((DataByteArray) obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "int for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
result = obj;
break;
case DataType.INTEGER:
result = Boolean.valueOf(((Integer) obj).intValue() != 0);;
break;
case DataType.DOUBLE:
result = Boolean.valueOf(((Double) obj).doubleValue() != 0.0D);
break;
case DataType.LONG:
result = Boolean.valueOf(((Long) obj).longValue() != 0L);
break;
case DataType.FLOAT:
result = Boolean.valueOf(((Float) obj).floatValue() != 0.0F);
break;
case DataType.CHARARRAY:
result = CastUtils.stringToBoolean((String)obj);
break;
case DataType.BIGINTEGER:
result = Boolean.valueOf(!BigInteger.ZERO.equals((BigInteger)obj));
break;
case DataType.BIGDECIMAL:
result = Boolean.valueOf(((BigDecimal)obj).signum() != 0);
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.INTEGER:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToInteger(((DataByteArray) obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "int for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
result = Integer.valueOf(1);
} else {
result = Integer.valueOf(0);
}
break;
case DataType.INTEGER:
result = obj;
break;
case DataType.DOUBLE:
result = Integer.valueOf(((Double)obj).intValue());
break;
case DataType.LONG:
result = Integer.valueOf(((Long)obj).intValue());
break;
case DataType.FLOAT:
result = Integer.valueOf(((Float)obj).intValue());
break;
case DataType.DATETIME:
result = Integer.valueOf(Long.valueOf(((DateTime)obj).getMillis()).intValue());
break;
case DataType.CHARARRAY:
result = CastUtils.stringToInteger((String)obj);
break;
case DataType.BIGINTEGER:
result = Integer.valueOf(((BigInteger)obj).intValue());
break;
case DataType.BIGDECIMAL:
result = Integer.valueOf(((BigDecimal)obj).intValue());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.DOUBLE:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToDouble(((DataByteArray) obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "double for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
result = new Double(1);
} else {
result = new Double(1);
}
break;
case DataType.INTEGER:
result = new Double(((Integer)obj).doubleValue());
break;
case DataType.DOUBLE:
result = (Double)obj;
break;
case DataType.LONG:
result = new Double(((Long)obj).doubleValue());
break;
case DataType.FLOAT:
result = new Double(((Float)obj).doubleValue());
break;
case DataType.DATETIME:
result = new Double(Long.valueOf(((DateTime)obj).getMillis()).doubleValue());
break;
case DataType.CHARARRAY:
result = CastUtils.stringToDouble((String)obj);
break;
case DataType.BIGINTEGER:
result = Double.valueOf(((BigInteger)obj).doubleValue());
break;
case DataType.BIGDECIMAL:
result = Double.valueOf(((BigDecimal)obj).doubleValue());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.LONG:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToLong(((DataByteArray)obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "long for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
result = Long.valueOf(1);
} else {
result = Long.valueOf(0);
}
break;
case DataType.INTEGER:
result = Long.valueOf(((Integer)obj).longValue());
break;
case DataType.DOUBLE:
result = Long.valueOf(((Double)obj).longValue());
break;
case DataType.LONG:
result = (Long)obj;
break;
case DataType.FLOAT:
result = Long.valueOf(((Float)obj).longValue());
break;
case DataType.DATETIME:
result = Long.valueOf(((DateTime)obj).getMillis());
break;
case DataType.CHARARRAY:
result = CastUtils.stringToLong((String)obj);
break;
case DataType.BIGINTEGER:
result = Long.valueOf(((BigInteger)obj).longValue());
break;
case DataType.BIGDECIMAL:
result = Long.valueOf(((BigDecimal)obj).longValue());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.FLOAT:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToFloat(((DataByteArray)obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "float for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
result = new Float(1);
} else {
result = new Float(0);
}
break;
case DataType.INTEGER:
result = new Float(((Integer) obj).floatValue());
break;
case DataType.DOUBLE:
result = new Float(((Double)obj).floatValue());
break;
case DataType.LONG:
result = new Float(((Long)obj).floatValue());
break;
case DataType.FLOAT:
result = obj;
break;
case DataType.DATETIME:
result = new Float(Long.valueOf(((DateTime)obj).getMillis()).floatValue());
break;
case DataType.CHARARRAY:
result = CastUtils.stringToFloat((String)obj);
break;
case DataType.BIGINTEGER:
result = Float.valueOf(((BigInteger)obj).floatValue());
break;
case DataType.BIGDECIMAL:
result = Float.valueOf(((BigDecimal)obj).floatValue());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.DATETIME:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToDateTime(((DataByteArray)obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "datetime for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.INTEGER:
result = new DateTime(((Integer)obj).longValue());
break;
case DataType.DOUBLE:
result = new DateTime(((Double)obj).longValue());
break;
case DataType.LONG:
result = new DateTime(((Long)obj).longValue());
break;
case DataType.FLOAT:
result = new DateTime(((Float)obj).longValue());
break;
case DataType.DATETIME:
result = (DateTime)obj;
break;
case DataType.CHARARRAY:
result = ToDate.extractDateTime((String) obj);
break;
case DataType.BIGINTEGER:
result = new DateTime(((BigInteger)obj).longValue());
break;
case DataType.BIGDECIMAL:
result = new DateTime(((BigDecimal)obj).longValue());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.CHARARRAY:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToCharArray(((DataByteArray)obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "float for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
//result = "1";
result = Boolean.TRUE.toString();
} else {
//result = "0";
result = Boolean.FALSE.toString();
}
break;
case DataType.INTEGER:
result = ((Integer) obj).toString();
break;
case DataType.DOUBLE:
result = ((Double) obj).toString();
break;
case DataType.LONG:
result = ((Long) obj).toString();
break;
case DataType.FLOAT:
result = ((Float) obj).toString();
break;
case DataType.DATETIME:
result = ((DateTime)obj).toString();
break;
case DataType.CHARARRAY:
result = obj;
break;
case DataType.BIGINTEGER:
result = ((BigInteger)obj).toString();
break;
case DataType.BIGDECIMAL:
result = ((BigDecimal)obj).toString();
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
break;
case DataType.BIGINTEGER:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToBigInteger(((DataByteArray)obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "BigInteger for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
result = BigInteger.ONE;
} else {
result = BigInteger.ZERO;
}
break;
case DataType.INTEGER:
result = BigInteger.valueOf(((Integer)obj).longValue());
break;
case DataType.DOUBLE:
result = BigInteger.valueOf(((Double)obj).longValue());
break;
case DataType.LONG:
result = BigInteger.valueOf(((Long)obj).longValue());
break;
case DataType.FLOAT:
result = BigInteger.valueOf(((Float)obj).longValue());
break;
case DataType.CHARARRAY:
result = new BigInteger((String)obj);
break;
case DataType.BIGINTEGER:
result = (BigInteger)obj;
break;
case DataType.BIGDECIMAL:
result = ((BigDecimal)obj).toBigInteger();
break;
case DataType.DATETIME:
result = BigInteger.valueOf(((DateTime)obj).getMillis());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
case DataType.BIGDECIMAL:
switch (DataType.findType(obj)) {
case DataType.BYTEARRAY:
if (null != caster) {
result = caster.bytesToBigDecimal(((DataByteArray)obj).get());
} else {
int errCode = 1075;
String msg = unknownByteArrayErrorMessage + "BigDecimal for " + this.getOriginalLocations();
throw new ExecException(msg, errCode, PigException.INPUT);
}
break;
case DataType.BOOLEAN:
if ((Boolean) obj) {
result = BigDecimal.ONE;
} else {
result = BigDecimal.ZERO;
}
break;
case DataType.INTEGER:
result = BigDecimal.valueOf(((Integer)obj).longValue());
break;
case DataType.DOUBLE:
result = BigDecimal.valueOf(((Double)obj).doubleValue());
break;
case DataType.LONG:
result = BigDecimal.valueOf(((Long)obj).longValue());
break;
case DataType.FLOAT:
result = BigDecimal.valueOf(((Float)obj).doubleValue());
break;
case DataType.CHARARRAY:
result = new BigDecimal((String)obj);
break;
case DataType.BIGINTEGER:
result = new BigDecimal((BigInteger)obj);
break;
case DataType.BIGDECIMAL:
result = (BigDecimal)obj;
break;
case DataType.DATETIME:
result = BigDecimal.valueOf(((DateTime)obj).getMillis());
break;
default:
throw new ExecException("Cannot convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
case DataType.BYTEARRAY:
//no-op (PIG-4933)
result = obj;
break;
default:
throw new ExecException("Don't know how to convert "+ obj + " to " + fs, 1120, PigException.INPUT);
}
return result;
}