private Object convertWithSchema()

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;
    }