@Override
  public Writable serialize(Object obj, ObjectInspector oi) throws SerDeException {
    if (oi.getCategory() != Category.STRUCT) {
      throw new VoltSerdeException(
          getClass().toString()
              + " can only serialize struct types, but we got: "
              + oi.getTypeName());
    }
    VoltRecord vr = new VoltRecord(m_voltConf.getTableName());
    StructObjectInspector soi = (StructObjectInspector) oi;
    List<? extends StructField> structFields = soi.getAllStructFieldRefs();
    List<Object> fieldValues = soi.getStructFieldsDataAsList(obj);

    final int size = m_oig.getColumnTypes().size();

    for (int i = 0; i < size; ++i) {
      ObjectInspector fieldOI = structFields.get(i).getFieldObjectInspector();
      PrimitiveObjectInspector poi = (PrimitiveObjectInspector) fieldOI;

      Object fieldValue = poi.getPrimitiveJavaObject(fieldValues.get(i));
      if (poi.getTypeInfo().equals(TypeInfoFactory.timestampTypeInfo)) {
        fieldValue = fieldValue != null ? new Date(((Timestamp) fieldValue).getTime()) : null;
      }
      vr.add(fieldValue);
    }

    return vr;
  }
  /**
   * Reads the following SERDEPROPERTIES
   *
   * <p>
   *
   * <ul>
   *   <li>{@code voltdb.servers} (required) comma separated list of VoltDB servers that comprise a
   *       VoltDB cluster
   *   <li>{@code voltdb.table} (required) destination VoltDB table
   *   <li>{@code voltdb.user} (optional) VoltDB user name
   *   <li>{@code voltdb.password} (optional) VoltDB user password
   * </ul>
   *
   * <p>and makes sure that the Hive table column types match the destination VoltDB column types
   */
  @Override
  public void initialize(Configuration conf, Properties props) throws SerDeException {

    String columnNamesPropVal = props.getProperty(serdeConstants.LIST_COLUMNS, "");
    String columnTypesPropVal = props.getProperty(serdeConstants.LIST_COLUMN_TYPES, "");
    String serversPropVal = props.getProperty(SERVERS_PROP, "");

    String table = props.getProperty(TABLE_PROP, "");
    String user = props.getProperty(USER_PROP);
    String password = props.getProperty(PASSWORD_PROP);

    if (serversPropVal.trim().isEmpty() || table.trim().isEmpty()) {
      throw new VoltSerdeException(
          "properties \""
              + SERVERS_PROP
              + "\", and \""
              + TABLE_PROP
              + "\" must be minimally defined");
    }

    List<String> columnNames = m_splitter.splitToList(columnNamesPropVal);
    List<TypeInfo> columnTypes = TypeInfoUtils.getTypeInfosFromTypeString(columnTypesPropVal);

    String[] servers = m_splitter.splitToList(serversPropVal).toArray(new String[0]);
    if (servers.length == 0) {
      throw new VoltSerdeException(
          "properties \""
              + SERVERS_PROP
              + "\", and \""
              + TABLE_PROP
              + "\" must be minimally defined");
    }

    if (conf != null) {
      VoltConfiguration.configureVoltDB(conf, servers, user, password, table);
    }

    VoltType[] voltTypes = null;
    m_voltConf = new VoltConfiguration(table, servers, user, password);
    try {
      m_voltConf.isMinimallyConfigured();
      voltTypes = m_voltConf.getTableColumnTypes();
    } catch (IOException e) {
      throw new VoltSerdeException("uanble to setup a VoltDB context", e);
    }
    m_oig = new VoltObjectInspectorGenerator(columnNames, columnTypes, voltTypes);
  }