/**
 * Autogenerated by Thrift Compiler (0.14.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.hadoop.hbase.thrift.generated;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * A Scan object is used to specify scanner parameters when opening a scanner.
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.14.1)", date = "2021-07-19")
public class TScan implements org.apache.thrift.TBase<TScan, TScan._Fields>, java.io.Serializable, Cloneable, Comparable<TScan> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TScan");

  private static final org.apache.thrift.protocol.TField START_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("startRow", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField STOP_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("stopRow", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)3);
  private static final org.apache.thrift.protocol.TField COLUMNS_FIELD_DESC = new org.apache.thrift.protocol.TField("columns", org.apache.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.thrift.protocol.TField CACHING_FIELD_DESC = new org.apache.thrift.protocol.TField("caching", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField FILTER_STRING_FIELD_DESC = new org.apache.thrift.protocol.TField("filterString", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField BATCH_SIZE_FIELD_DESC = new org.apache.thrift.protocol.TField("batchSize", org.apache.thrift.protocol.TType.I32, (short)7);
  private static final org.apache.thrift.protocol.TField SORT_COLUMNS_FIELD_DESC = new org.apache.thrift.protocol.TField("sortColumns", org.apache.thrift.protocol.TType.BOOL, (short)8);
  private static final org.apache.thrift.protocol.TField REVERSED_FIELD_DESC = new org.apache.thrift.protocol.TField("reversed", org.apache.thrift.protocol.TType.BOOL, (short)9);
  private static final org.apache.thrift.protocol.TField CACHE_BLOCKS_FIELD_DESC = new org.apache.thrift.protocol.TField("cacheBlocks", org.apache.thrift.protocol.TType.BOOL, (short)10);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TScanStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TScanTupleSchemeFactory();

  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer startRow; // optional
  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer stopRow; // optional
  public long timestamp; // optional
  public @org.apache.thrift.annotation.Nullable java.util.List<java.nio.ByteBuffer> columns; // optional
  public int caching; // optional
  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer filterString; // optional
  public int batchSize; // optional
  public boolean sortColumns; // optional
  public boolean reversed; // optional
  public boolean cacheBlocks; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    START_ROW((short)1, "startRow"),
    STOP_ROW((short)2, "stopRow"),
    TIMESTAMP((short)3, "timestamp"),
    COLUMNS((short)4, "columns"),
    CACHING((short)5, "caching"),
    FILTER_STRING((short)6, "filterString"),
    BATCH_SIZE((short)7, "batchSize"),
    SORT_COLUMNS((short)8, "sortColumns"),
    REVERSED((short)9, "reversed"),
    CACHE_BLOCKS((short)10, "cacheBlocks");

    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

    static {
      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // START_ROW
          return START_ROW;
        case 2: // STOP_ROW
          return STOP_ROW;
        case 3: // TIMESTAMP
          return TIMESTAMP;
        case 4: // COLUMNS
          return COLUMNS;
        case 5: // CACHING
          return CACHING;
        case 6: // FILTER_STRING
          return FILTER_STRING;
        case 7: // BATCH_SIZE
          return BATCH_SIZE;
        case 8: // SORT_COLUMNS
          return SORT_COLUMNS;
        case 9: // REVERSED
          return REVERSED;
        case 10: // CACHE_BLOCKS
          return CACHE_BLOCKS;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

    _Fields(short thriftId, java.lang.String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __TIMESTAMP_ISSET_ID = 0;
  private static final int __CACHING_ISSET_ID = 1;
  private static final int __BATCHSIZE_ISSET_ID = 2;
  private static final int __SORTCOLUMNS_ISSET_ID = 3;
  private static final int __REVERSED_ISSET_ID = 4;
  private static final int __CACHEBLOCKS_ISSET_ID = 5;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.START_ROW,_Fields.STOP_ROW,_Fields.TIMESTAMP,_Fields.COLUMNS,_Fields.CACHING,_Fields.FILTER_STRING,_Fields.BATCH_SIZE,_Fields.SORT_COLUMNS,_Fields.REVERSED,_Fields.CACHE_BLOCKS};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.START_ROW, new org.apache.thrift.meta_data.FieldMetaData("startRow", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , "Text")));
    tmpMap.put(_Fields.STOP_ROW, new org.apache.thrift.meta_data.FieldMetaData("stopRow", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , "Text")));
    tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.COLUMNS, new org.apache.thrift.meta_data.FieldMetaData("columns", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , "Text"))));
    tmpMap.put(_Fields.CACHING, new org.apache.thrift.meta_data.FieldMetaData("caching", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.FILTER_STRING, new org.apache.thrift.meta_data.FieldMetaData("filterString", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , "Text")));
    tmpMap.put(_Fields.BATCH_SIZE, new org.apache.thrift.meta_data.FieldMetaData("batchSize", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.SORT_COLUMNS, new org.apache.thrift.meta_data.FieldMetaData("sortColumns", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.REVERSED, new org.apache.thrift.meta_data.FieldMetaData("reversed", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.CACHE_BLOCKS, new org.apache.thrift.meta_data.FieldMetaData("cacheBlocks", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TScan.class, metaDataMap);
  }

  public TScan() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TScan(TScan other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetStartRow()) {
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
    }
    if (other.isSetStopRow()) {
      this.stopRow = org.apache.thrift.TBaseHelper.copyBinary(other.stopRow);
    }
    this.timestamp = other.timestamp;
    if (other.isSetColumns()) {
      java.util.List<java.nio.ByteBuffer> __this__columns = new java.util.ArrayList<java.nio.ByteBuffer>(other.columns.size());
      for (java.nio.ByteBuffer other_element : other.columns) {
        __this__columns.add(org.apache.thrift.TBaseHelper.copyBinary(other_element));
      }
      this.columns = __this__columns;
    }
    this.caching = other.caching;
    if (other.isSetFilterString()) {
      this.filterString = org.apache.thrift.TBaseHelper.copyBinary(other.filterString);
    }
    this.batchSize = other.batchSize;
    this.sortColumns = other.sortColumns;
    this.reversed = other.reversed;
    this.cacheBlocks = other.cacheBlocks;
  }

  public TScan deepCopy() {
    return new TScan(this);
  }

  @Override
  public void clear() {
    this.startRow = null;
    this.stopRow = null;
    setTimestampIsSet(false);
    this.timestamp = 0;
    this.columns = null;
    setCachingIsSet(false);
    this.caching = 0;
    this.filterString = null;
    setBatchSizeIsSet(false);
    this.batchSize = 0;
    setSortColumnsIsSet(false);
    this.sortColumns = false;
    setReversedIsSet(false);
    this.reversed = false;
    setCacheBlocksIsSet(false);
    this.cacheBlocks = false;
  }

  public byte[] getStartRow() {
    setStartRow(org.apache.thrift.TBaseHelper.rightSize(startRow));
    return startRow == null ? null : startRow.array();
  }

  public java.nio.ByteBuffer bufferForStartRow() {
    return org.apache.thrift.TBaseHelper.copyBinary(startRow);
  }

  public TScan setStartRow(byte[] startRow) {
    this.startRow = startRow == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(startRow.clone());
    return this;
  }

  public TScan setStartRow(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer startRow) {
    this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
    return this;
  }

  public void unsetStartRow() {
    this.startRow = null;
  }

  /** Returns true if field startRow is set (has been assigned a value) and false otherwise */
  public boolean isSetStartRow() {
    return this.startRow != null;
  }

  public void setStartRowIsSet(boolean value) {
    if (!value) {
      this.startRow = null;
    }
  }

  public byte[] getStopRow() {
    setStopRow(org.apache.thrift.TBaseHelper.rightSize(stopRow));
    return stopRow == null ? null : stopRow.array();
  }

  public java.nio.ByteBuffer bufferForStopRow() {
    return org.apache.thrift.TBaseHelper.copyBinary(stopRow);
  }

  public TScan setStopRow(byte[] stopRow) {
    this.stopRow = stopRow == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(stopRow.clone());
    return this;
  }

  public TScan setStopRow(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer stopRow) {
    this.stopRow = org.apache.thrift.TBaseHelper.copyBinary(stopRow);
    return this;
  }

  public void unsetStopRow() {
    this.stopRow = null;
  }

  /** Returns true if field stopRow is set (has been assigned a value) and false otherwise */
  public boolean isSetStopRow() {
    return this.stopRow != null;
  }

  public void setStopRowIsSet(boolean value) {
    if (!value) {
      this.stopRow = null;
    }
  }

  public long getTimestamp() {
    return this.timestamp;
  }

  public TScan setTimestamp(long timestamp) {
    this.timestamp = timestamp;
    setTimestampIsSet(true);
    return this;
  }

  public void unsetTimestamp() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
  }

  /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */
  public boolean isSetTimestamp() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
  }

  public void setTimestampIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
  }

  public int getColumnsSize() {
    return (this.columns == null) ? 0 : this.columns.size();
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<java.nio.ByteBuffer> getColumnsIterator() {
    return (this.columns == null) ? null : this.columns.iterator();
  }

  public void addToColumns(java.nio.ByteBuffer elem) {
    if (this.columns == null) {
      this.columns = new java.util.ArrayList<java.nio.ByteBuffer>();
    }
    this.columns.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<java.nio.ByteBuffer> getColumns() {
    return this.columns;
  }

  public TScan setColumns(@org.apache.thrift.annotation.Nullable java.util.List<java.nio.ByteBuffer> columns) {
    this.columns = columns;
    return this;
  }

  public void unsetColumns() {
    this.columns = null;
  }

  /** Returns true if field columns is set (has been assigned a value) and false otherwise */
  public boolean isSetColumns() {
    return this.columns != null;
  }

  public void setColumnsIsSet(boolean value) {
    if (!value) {
      this.columns = null;
    }
  }

  public int getCaching() {
    return this.caching;
  }

  public TScan setCaching(int caching) {
    this.caching = caching;
    setCachingIsSet(true);
    return this;
  }

  public void unsetCaching() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CACHING_ISSET_ID);
  }

  /** Returns true if field caching is set (has been assigned a value) and false otherwise */
  public boolean isSetCaching() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CACHING_ISSET_ID);
  }

  public void setCachingIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CACHING_ISSET_ID, value);
  }

  public byte[] getFilterString() {
    setFilterString(org.apache.thrift.TBaseHelper.rightSize(filterString));
    return filterString == null ? null : filterString.array();
  }

  public java.nio.ByteBuffer bufferForFilterString() {
    return org.apache.thrift.TBaseHelper.copyBinary(filterString);
  }

  public TScan setFilterString(byte[] filterString) {
    this.filterString = filterString == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(filterString.clone());
    return this;
  }

  public TScan setFilterString(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer filterString) {
    this.filterString = org.apache.thrift.TBaseHelper.copyBinary(filterString);
    return this;
  }

  public void unsetFilterString() {
    this.filterString = null;
  }

  /** Returns true if field filterString is set (has been assigned a value) and false otherwise */
  public boolean isSetFilterString() {
    return this.filterString != null;
  }

  public void setFilterStringIsSet(boolean value) {
    if (!value) {
      this.filterString = null;
    }
  }

  public int getBatchSize() {
    return this.batchSize;
  }

  public TScan setBatchSize(int batchSize) {
    this.batchSize = batchSize;
    setBatchSizeIsSet(true);
    return this;
  }

  public void unsetBatchSize() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __BATCHSIZE_ISSET_ID);
  }

  /** Returns true if field batchSize is set (has been assigned a value) and false otherwise */
  public boolean isSetBatchSize() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __BATCHSIZE_ISSET_ID);
  }

  public void setBatchSizeIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __BATCHSIZE_ISSET_ID, value);
  }

  public boolean isSortColumns() {
    return this.sortColumns;
  }

  public TScan setSortColumns(boolean sortColumns) {
    this.sortColumns = sortColumns;
    setSortColumnsIsSet(true);
    return this;
  }

  public void unsetSortColumns() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SORTCOLUMNS_ISSET_ID);
  }

  /** Returns true if field sortColumns is set (has been assigned a value) and false otherwise */
  public boolean isSetSortColumns() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SORTCOLUMNS_ISSET_ID);
  }

  public void setSortColumnsIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SORTCOLUMNS_ISSET_ID, value);
  }

  public boolean isReversed() {
    return this.reversed;
  }

  public TScan setReversed(boolean reversed) {
    this.reversed = reversed;
    setReversedIsSet(true);
    return this;
  }

  public void unsetReversed() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __REVERSED_ISSET_ID);
  }

  /** Returns true if field reversed is set (has been assigned a value) and false otherwise */
  public boolean isSetReversed() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __REVERSED_ISSET_ID);
  }

  public void setReversedIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __REVERSED_ISSET_ID, value);
  }

  public boolean isCacheBlocks() {
    return this.cacheBlocks;
  }

  public TScan setCacheBlocks(boolean cacheBlocks) {
    this.cacheBlocks = cacheBlocks;
    setCacheBlocksIsSet(true);
    return this;
  }

  public void unsetCacheBlocks() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CACHEBLOCKS_ISSET_ID);
  }

  /** Returns true if field cacheBlocks is set (has been assigned a value) and false otherwise */
  public boolean isSetCacheBlocks() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CACHEBLOCKS_ISSET_ID);
  }

  public void setCacheBlocksIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CACHEBLOCKS_ISSET_ID, value);
  }

  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case START_ROW:
      if (value == null) {
        unsetStartRow();
      } else {
        if (value instanceof byte[]) {
          setStartRow((byte[])value);
        } else {
          setStartRow((java.nio.ByteBuffer)value);
        }
      }
      break;

    case STOP_ROW:
      if (value == null) {
        unsetStopRow();
      } else {
        if (value instanceof byte[]) {
          setStopRow((byte[])value);
        } else {
          setStopRow((java.nio.ByteBuffer)value);
        }
      }
      break;

    case TIMESTAMP:
      if (value == null) {
        unsetTimestamp();
      } else {
        setTimestamp((java.lang.Long)value);
      }
      break;

    case COLUMNS:
      if (value == null) {
        unsetColumns();
      } else {
        setColumns((java.util.List<java.nio.ByteBuffer>)value);
      }
      break;

    case CACHING:
      if (value == null) {
        unsetCaching();
      } else {
        setCaching((java.lang.Integer)value);
      }
      break;

    case FILTER_STRING:
      if (value == null) {
        unsetFilterString();
      } else {
        if (value instanceof byte[]) {
          setFilterString((byte[])value);
        } else {
          setFilterString((java.nio.ByteBuffer)value);
        }
      }
      break;

    case BATCH_SIZE:
      if (value == null) {
        unsetBatchSize();
      } else {
        setBatchSize((java.lang.Integer)value);
      }
      break;

    case SORT_COLUMNS:
      if (value == null) {
        unsetSortColumns();
      } else {
        setSortColumns((java.lang.Boolean)value);
      }
      break;

    case REVERSED:
      if (value == null) {
        unsetReversed();
      } else {
        setReversed((java.lang.Boolean)value);
      }
      break;

    case CACHE_BLOCKS:
      if (value == null) {
        unsetCacheBlocks();
      } else {
        setCacheBlocks((java.lang.Boolean)value);
      }
      break;

    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case START_ROW:
      return getStartRow();

    case STOP_ROW:
      return getStopRow();

    case TIMESTAMP:
      return getTimestamp();

    case COLUMNS:
      return getColumns();

    case CACHING:
      return getCaching();

    case FILTER_STRING:
      return getFilterString();

    case BATCH_SIZE:
      return getBatchSize();

    case SORT_COLUMNS:
      return isSortColumns();

    case REVERSED:
      return isReversed();

    case CACHE_BLOCKS:
      return isCacheBlocks();

    }
    throw new java.lang.IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new java.lang.IllegalArgumentException();
    }

    switch (field) {
    case START_ROW:
      return isSetStartRow();
    case STOP_ROW:
      return isSetStopRow();
    case TIMESTAMP:
      return isSetTimestamp();
    case COLUMNS:
      return isSetColumns();
    case CACHING:
      return isSetCaching();
    case FILTER_STRING:
      return isSetFilterString();
    case BATCH_SIZE:
      return isSetBatchSize();
    case SORT_COLUMNS:
      return isSetSortColumns();
    case REVERSED:
      return isSetReversed();
    case CACHE_BLOCKS:
      return isSetCacheBlocks();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.Object that) {
    if (that instanceof TScan)
      return this.equals((TScan)that);
    return false;
  }

  public boolean equals(TScan that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_startRow = true && this.isSetStartRow();
    boolean that_present_startRow = true && that.isSetStartRow();
    if (this_present_startRow || that_present_startRow) {
      if (!(this_present_startRow && that_present_startRow))
        return false;
      if (!this.startRow.equals(that.startRow))
        return false;
    }

    boolean this_present_stopRow = true && this.isSetStopRow();
    boolean that_present_stopRow = true && that.isSetStopRow();
    if (this_present_stopRow || that_present_stopRow) {
      if (!(this_present_stopRow && that_present_stopRow))
        return false;
      if (!this.stopRow.equals(that.stopRow))
        return false;
    }

    boolean this_present_timestamp = true && this.isSetTimestamp();
    boolean that_present_timestamp = true && that.isSetTimestamp();
    if (this_present_timestamp || that_present_timestamp) {
      if (!(this_present_timestamp && that_present_timestamp))
        return false;
      if (this.timestamp != that.timestamp)
        return false;
    }

    boolean this_present_columns = true && this.isSetColumns();
    boolean that_present_columns = true && that.isSetColumns();
    if (this_present_columns || that_present_columns) {
      if (!(this_present_columns && that_present_columns))
        return false;
      if (!this.columns.equals(that.columns))
        return false;
    }

    boolean this_present_caching = true && this.isSetCaching();
    boolean that_present_caching = true && that.isSetCaching();
    if (this_present_caching || that_present_caching) {
      if (!(this_present_caching && that_present_caching))
        return false;
      if (this.caching != that.caching)
        return false;
    }

    boolean this_present_filterString = true && this.isSetFilterString();
    boolean that_present_filterString = true && that.isSetFilterString();
    if (this_present_filterString || that_present_filterString) {
      if (!(this_present_filterString && that_present_filterString))
        return false;
      if (!this.filterString.equals(that.filterString))
        return false;
    }

    boolean this_present_batchSize = true && this.isSetBatchSize();
    boolean that_present_batchSize = true && that.isSetBatchSize();
    if (this_present_batchSize || that_present_batchSize) {
      if (!(this_present_batchSize && that_present_batchSize))
        return false;
      if (this.batchSize != that.batchSize)
        return false;
    }

    boolean this_present_sortColumns = true && this.isSetSortColumns();
    boolean that_present_sortColumns = true && that.isSetSortColumns();
    if (this_present_sortColumns || that_present_sortColumns) {
      if (!(this_present_sortColumns && that_present_sortColumns))
        return false;
      if (this.sortColumns != that.sortColumns)
        return false;
    }

    boolean this_present_reversed = true && this.isSetReversed();
    boolean that_present_reversed = true && that.isSetReversed();
    if (this_present_reversed || that_present_reversed) {
      if (!(this_present_reversed && that_present_reversed))
        return false;
      if (this.reversed != that.reversed)
        return false;
    }

    boolean this_present_cacheBlocks = true && this.isSetCacheBlocks();
    boolean that_present_cacheBlocks = true && that.isSetCacheBlocks();
    if (this_present_cacheBlocks || that_present_cacheBlocks) {
      if (!(this_present_cacheBlocks && that_present_cacheBlocks))
        return false;
      if (this.cacheBlocks != that.cacheBlocks)
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
    if (isSetStartRow())
      hashCode = hashCode * 8191 + startRow.hashCode();

    hashCode = hashCode * 8191 + ((isSetStopRow()) ? 131071 : 524287);
    if (isSetStopRow())
      hashCode = hashCode * 8191 + stopRow.hashCode();

    hashCode = hashCode * 8191 + ((isSetTimestamp()) ? 131071 : 524287);
    if (isSetTimestamp())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timestamp);

    hashCode = hashCode * 8191 + ((isSetColumns()) ? 131071 : 524287);
    if (isSetColumns())
      hashCode = hashCode * 8191 + columns.hashCode();

    hashCode = hashCode * 8191 + ((isSetCaching()) ? 131071 : 524287);
    if (isSetCaching())
      hashCode = hashCode * 8191 + caching;

    hashCode = hashCode * 8191 + ((isSetFilterString()) ? 131071 : 524287);
    if (isSetFilterString())
      hashCode = hashCode * 8191 + filterString.hashCode();

    hashCode = hashCode * 8191 + ((isSetBatchSize()) ? 131071 : 524287);
    if (isSetBatchSize())
      hashCode = hashCode * 8191 + batchSize;

    hashCode = hashCode * 8191 + ((isSetSortColumns()) ? 131071 : 524287);
    if (isSetSortColumns())
      hashCode = hashCode * 8191 + ((sortColumns) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetReversed()) ? 131071 : 524287);
    if (isSetReversed())
      hashCode = hashCode * 8191 + ((reversed) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetCacheBlocks()) ? 131071 : 524287);
    if (isSetCacheBlocks())
      hashCode = hashCode * 8191 + ((cacheBlocks) ? 131071 : 524287);

    return hashCode;
  }

  @Override
  public int compareTo(TScan other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetStartRow(), other.isSetStartRow());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStartRow()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startRow, other.startRow);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetStopRow(), other.isSetStopRow());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStopRow()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stopRow, other.stopRow);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTimestamp(), other.isSetTimestamp());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTimestamp()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, other.timestamp);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetColumns(), other.isSetColumns());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetColumns()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.columns, other.columns);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetCaching(), other.isSetCaching());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCaching()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.caching, other.caching);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetFilterString(), other.isSetFilterString());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFilterString()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.filterString, other.filterString);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetBatchSize(), other.isSetBatchSize());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBatchSize()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.batchSize, other.batchSize);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetSortColumns(), other.isSetSortColumns());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSortColumns()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sortColumns, other.sortColumns);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetReversed(), other.isSetReversed());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReversed()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reversed, other.reversed);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetCacheBlocks(), other.isSetCacheBlocks());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCacheBlocks()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cacheBlocks, other.cacheBlocks);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.thrift.annotation.Nullable
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("TScan(");
    boolean first = true;

    if (isSetStartRow()) {
      sb.append("startRow:");
      if (this.startRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.startRow, sb);
      }
      first = false;
    }
    if (isSetStopRow()) {
      if (!first) sb.append(", ");
      sb.append("stopRow:");
      if (this.stopRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.stopRow, sb);
      }
      first = false;
    }
    if (isSetTimestamp()) {
      if (!first) sb.append(", ");
      sb.append("timestamp:");
      sb.append(this.timestamp);
      first = false;
    }
    if (isSetColumns()) {
      if (!first) sb.append(", ");
      sb.append("columns:");
      if (this.columns == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.columns, sb);
      }
      first = false;
    }
    if (isSetCaching()) {
      if (!first) sb.append(", ");
      sb.append("caching:");
      sb.append(this.caching);
      first = false;
    }
    if (isSetFilterString()) {
      if (!first) sb.append(", ");
      sb.append("filterString:");
      if (this.filterString == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.filterString, sb);
      }
      first = false;
    }
    if (isSetBatchSize()) {
      if (!first) sb.append(", ");
      sb.append("batchSize:");
      sb.append(this.batchSize);
      first = false;
    }
    if (isSetSortColumns()) {
      if (!first) sb.append(", ");
      sb.append("sortColumns:");
      sb.append(this.sortColumns);
      first = false;
    }
    if (isSetReversed()) {
      if (!first) sb.append(", ");
      sb.append("reversed:");
      sb.append(this.reversed);
      first = false;
    }
    if (isSetCacheBlocks()) {
      if (!first) sb.append(", ");
      sb.append("cacheBlocks:");
      sb.append(this.cacheBlocks);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class TScanStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public TScanStandardScheme getScheme() {
      return new TScanStandardScheme();
    }
  }

  private static class TScanStandardScheme extends org.apache.thrift.scheme.StandardScheme<TScan> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TScan struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // START_ROW
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.startRow = iprot.readBinary();
              struct.setStartRowIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // STOP_ROW
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.stopRow = iprot.readBinary();
              struct.setStopRowIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TIMESTAMP
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.timestamp = iprot.readI64();
              struct.setTimestampIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COLUMNS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list26 = iprot.readListBegin();
                struct.columns = new java.util.ArrayList<java.nio.ByteBuffer>(_list26.size);
                @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer _elem27;
                for (int _i28 = 0; _i28 < _list26.size; ++_i28)
                {
                  _elem27 = iprot.readBinary();
                  struct.columns.add(_elem27);
                }
                iprot.readListEnd();
              }
              struct.setColumnsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // CACHING
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.caching = iprot.readI32();
              struct.setCachingIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // FILTER_STRING
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.filterString = iprot.readBinary();
              struct.setFilterStringIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // BATCH_SIZE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.batchSize = iprot.readI32();
              struct.setBatchSizeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // SORT_COLUMNS
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.sortColumns = iprot.readBool();
              struct.setSortColumnsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // REVERSED
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.reversed = iprot.readBool();
              struct.setReversedIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // CACHE_BLOCKS
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.cacheBlocks = iprot.readBool();
              struct.setCacheBlocksIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, TScan struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.startRow != null) {
        if (struct.isSetStartRow()) {
          oprot.writeFieldBegin(START_ROW_FIELD_DESC);
          oprot.writeBinary(struct.startRow);
          oprot.writeFieldEnd();
        }
      }
      if (struct.stopRow != null) {
        if (struct.isSetStopRow()) {
          oprot.writeFieldBegin(STOP_ROW_FIELD_DESC);
          oprot.writeBinary(struct.stopRow);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetTimestamp()) {
        oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
        oprot.writeI64(struct.timestamp);
        oprot.writeFieldEnd();
      }
      if (struct.columns != null) {
        if (struct.isSetColumns()) {
          oprot.writeFieldBegin(COLUMNS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.columns.size()));
            for (java.nio.ByteBuffer _iter29 : struct.columns)
            {
              oprot.writeBinary(_iter29);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetCaching()) {
        oprot.writeFieldBegin(CACHING_FIELD_DESC);
        oprot.writeI32(struct.caching);
        oprot.writeFieldEnd();
      }
      if (struct.filterString != null) {
        if (struct.isSetFilterString()) {
          oprot.writeFieldBegin(FILTER_STRING_FIELD_DESC);
          oprot.writeBinary(struct.filterString);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetBatchSize()) {
        oprot.writeFieldBegin(BATCH_SIZE_FIELD_DESC);
        oprot.writeI32(struct.batchSize);
        oprot.writeFieldEnd();
      }
      if (struct.isSetSortColumns()) {
        oprot.writeFieldBegin(SORT_COLUMNS_FIELD_DESC);
        oprot.writeBool(struct.sortColumns);
        oprot.writeFieldEnd();
      }
      if (struct.isSetReversed()) {
        oprot.writeFieldBegin(REVERSED_FIELD_DESC);
        oprot.writeBool(struct.reversed);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCacheBlocks()) {
        oprot.writeFieldBegin(CACHE_BLOCKS_FIELD_DESC);
        oprot.writeBool(struct.cacheBlocks);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TScanTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public TScanTupleScheme getScheme() {
      return new TScanTupleScheme();
    }
  }

  private static class TScanTupleScheme extends org.apache.thrift.scheme.TupleScheme<TScan> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TScan struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetStartRow()) {
        optionals.set(0);
      }
      if (struct.isSetStopRow()) {
        optionals.set(1);
      }
      if (struct.isSetTimestamp()) {
        optionals.set(2);
      }
      if (struct.isSetColumns()) {
        optionals.set(3);
      }
      if (struct.isSetCaching()) {
        optionals.set(4);
      }
      if (struct.isSetFilterString()) {
        optionals.set(5);
      }
      if (struct.isSetBatchSize()) {
        optionals.set(6);
      }
      if (struct.isSetSortColumns()) {
        optionals.set(7);
      }
      if (struct.isSetReversed()) {
        optionals.set(8);
      }
      if (struct.isSetCacheBlocks()) {
        optionals.set(9);
      }
      oprot.writeBitSet(optionals, 10);
      if (struct.isSetStartRow()) {
        oprot.writeBinary(struct.startRow);
      }
      if (struct.isSetStopRow()) {
        oprot.writeBinary(struct.stopRow);
      }
      if (struct.isSetTimestamp()) {
        oprot.writeI64(struct.timestamp);
      }
      if (struct.isSetColumns()) {
        {
          oprot.writeI32(struct.columns.size());
          for (java.nio.ByteBuffer _iter30 : struct.columns)
          {
            oprot.writeBinary(_iter30);
          }
        }
      }
      if (struct.isSetCaching()) {
        oprot.writeI32(struct.caching);
      }
      if (struct.isSetFilterString()) {
        oprot.writeBinary(struct.filterString);
      }
      if (struct.isSetBatchSize()) {
        oprot.writeI32(struct.batchSize);
      }
      if (struct.isSetSortColumns()) {
        oprot.writeBool(struct.sortColumns);
      }
      if (struct.isSetReversed()) {
        oprot.writeBool(struct.reversed);
      }
      if (struct.isSetCacheBlocks()) {
        oprot.writeBool(struct.cacheBlocks);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TScan struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(10);
      if (incoming.get(0)) {
        struct.startRow = iprot.readBinary();
        struct.setStartRowIsSet(true);
      }
      if (incoming.get(1)) {
        struct.stopRow = iprot.readBinary();
        struct.setStopRowIsSet(true);
      }
      if (incoming.get(2)) {
        struct.timestamp = iprot.readI64();
        struct.setTimestampIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list31 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRING);
          struct.columns = new java.util.ArrayList<java.nio.ByteBuffer>(_list31.size);
          @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer _elem32;
          for (int _i33 = 0; _i33 < _list31.size; ++_i33)
          {
            _elem32 = iprot.readBinary();
            struct.columns.add(_elem32);
          }
        }
        struct.setColumnsIsSet(true);
      }
      if (incoming.get(4)) {
        struct.caching = iprot.readI32();
        struct.setCachingIsSet(true);
      }
      if (incoming.get(5)) {
        struct.filterString = iprot.readBinary();
        struct.setFilterStringIsSet(true);
      }
      if (incoming.get(6)) {
        struct.batchSize = iprot.readI32();
        struct.setBatchSizeIsSet(true);
      }
      if (incoming.get(7)) {
        struct.sortColumns = iprot.readBool();
        struct.setSortColumnsIsSet(true);
      }
      if (incoming.get(8)) {
        struct.reversed = iprot.readBool();
        struct.setReversedIsSet(true);
      }
      if (incoming.get(9)) {
        struct.cacheBlocks = iprot.readBool();
        struct.setCacheBlocksIsSet(true);
      }
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

