// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "kudu/client/schema.h"

#include <memory>
#include <ostream>
#include <unordered_map>
#include <utility>

#include <boost/optional/optional.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>

#include "kudu/client/schema-internal.h"
#include "kudu/client/value-internal.h"
#include "kudu/client/value.h"
#include "kudu/common/common.pb.h"
#include "kudu/common/partial_row.h"
#include "kudu/common/schema.h"
#include "kudu/common/types.h"
#include "kudu/gutil/casts.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/util/char_util.h"
#include "kudu/util/compression/compression.pb.h"
#include "kudu/util/decimal_util.h"
#include "kudu/util/slice.h"
#include "kudu/util/string_case.h"

DEFINE_bool(show_attributes, false,
            "Whether to show column attributes, including column encoding type, "
            "compression type, and default read/write value.");

MAKE_ENUM_LIMITS(kudu::client::KuduColumnStorageAttributes::EncodingType,
                 kudu::client::KuduColumnStorageAttributes::AUTO_ENCODING,
                 kudu::client::KuduColumnStorageAttributes::RLE);

MAKE_ENUM_LIMITS(kudu::client::KuduColumnStorageAttributes::CompressionType,
                 kudu::client::KuduColumnStorageAttributes::DEFAULT_COMPRESSION,
                 kudu::client::KuduColumnStorageAttributes::ZLIB);

MAKE_ENUM_LIMITS(kudu::client::KuduColumnSchema::DataType,
                 kudu::client::KuduColumnSchema::INT8,
                 kudu::client::KuduColumnSchema::BOOL);

using std::string;
using std::unique_ptr;
using std::unordered_map;
using std::vector;
using strings::Substitute;

namespace kudu {
namespace client {

kudu::EncodingType ToInternalEncodingType(KuduColumnStorageAttributes::EncodingType type) {
  switch (type) {
    case KuduColumnStorageAttributes::AUTO_ENCODING: return kudu::AUTO_ENCODING;
    case KuduColumnStorageAttributes::PLAIN_ENCODING: return kudu::PLAIN_ENCODING;
    case KuduColumnStorageAttributes::PREFIX_ENCODING: return kudu::PREFIX_ENCODING;
    case KuduColumnStorageAttributes::DICT_ENCODING: return kudu::DICT_ENCODING;
    case KuduColumnStorageAttributes::GROUP_VARINT: return kudu::GROUP_VARINT;
    case KuduColumnStorageAttributes::RLE: return kudu::RLE;
    case KuduColumnStorageAttributes::BIT_SHUFFLE: return kudu::BIT_SHUFFLE;
    default: LOG(FATAL) << "Unexpected encoding type: " << type;
  }
}

KuduColumnStorageAttributes::EncodingType FromInternalEncodingType(kudu::EncodingType type) {
  switch (type) {
    case kudu::AUTO_ENCODING: return KuduColumnStorageAttributes::AUTO_ENCODING;
    case kudu::PLAIN_ENCODING: return KuduColumnStorageAttributes::PLAIN_ENCODING;
    case kudu::PREFIX_ENCODING: return KuduColumnStorageAttributes::PREFIX_ENCODING;
    case kudu::DICT_ENCODING: return KuduColumnStorageAttributes::DICT_ENCODING;
    case kudu::GROUP_VARINT: return KuduColumnStorageAttributes::GROUP_VARINT;
    case kudu::RLE: return KuduColumnStorageAttributes::RLE;
    case kudu::BIT_SHUFFLE: return KuduColumnStorageAttributes::BIT_SHUFFLE;
    default: LOG(FATAL) << "Unexpected internal encoding type: " << type;
  }
}

kudu::CompressionType ToInternalCompressionType(KuduColumnStorageAttributes::CompressionType type) {
  switch (type) {
    case KuduColumnStorageAttributes::DEFAULT_COMPRESSION: return kudu::DEFAULT_COMPRESSION;
    case KuduColumnStorageAttributes::NO_COMPRESSION: return kudu::NO_COMPRESSION;
    case KuduColumnStorageAttributes::SNAPPY: return kudu::SNAPPY;
    case KuduColumnStorageAttributes::LZ4: return kudu::LZ4;
    case KuduColumnStorageAttributes::ZLIB: return kudu::ZLIB;
    default: LOG(FATAL) << "Unexpected compression type" << type;
  }
}

KuduColumnStorageAttributes::CompressionType FromInternalCompressionType(
    kudu::CompressionType type) {
  switch (type) {
    case kudu::DEFAULT_COMPRESSION: return KuduColumnStorageAttributes::DEFAULT_COMPRESSION;
    case kudu::NO_COMPRESSION: return KuduColumnStorageAttributes::NO_COMPRESSION;
    case kudu::SNAPPY: return KuduColumnStorageAttributes::SNAPPY;
    case kudu::LZ4: return KuduColumnStorageAttributes::LZ4;
    case kudu::ZLIB: return KuduColumnStorageAttributes::ZLIB;
    default: LOG(FATAL) << "Unexpected internal compression type: " << type;
  }
}

kudu::DataType ToInternalDataType(KuduColumnSchema::DataType type,
                                  const KuduColumnTypeAttributes& attributes) {
  switch (type) {
    case KuduColumnSchema::INT8: return kudu::INT8;
    case KuduColumnSchema::INT16: return kudu::INT16;
    case KuduColumnSchema::INT32: return kudu::INT32;
    case KuduColumnSchema::INT64: return kudu::INT64;
    case KuduColumnSchema::UNIXTIME_MICROS: return kudu::UNIXTIME_MICROS;
    case KuduColumnSchema::DATE: return kudu::DATE;
    case KuduColumnSchema::FLOAT: return kudu::FLOAT;
    case KuduColumnSchema::DOUBLE: return kudu::DOUBLE;
    case KuduColumnSchema::VARCHAR: return kudu::VARCHAR;
    case KuduColumnSchema::STRING: return kudu::STRING;
    case KuduColumnSchema::BINARY: return kudu::BINARY;
    case KuduColumnSchema::BOOL: return kudu::BOOL;
    case KuduColumnSchema::DECIMAL:
      if (attributes.precision() <= kMaxDecimal32Precision) {
        return kudu::DECIMAL32;
      } else if (attributes.precision() <= kMaxDecimal64Precision) {
        return kudu::DECIMAL64;
      } else if (attributes.precision() <= kMaxDecimal128Precision) {
        return kudu::DECIMAL128;
      } else {
        LOG(FATAL) << "Unsupported decimal type precision: " << attributes.precision();
      }
    default: LOG(FATAL) << "Unexpected data type: " << type;
  }
}

KuduColumnSchema::DataType FromInternalDataType(kudu::DataType type) {
  switch (type) {
    case kudu::INT8: return KuduColumnSchema::INT8;
    case kudu::INT16: return KuduColumnSchema::INT16;
    case kudu::INT32: return KuduColumnSchema::INT32;
    case kudu::INT64: return KuduColumnSchema::INT64;
    case kudu::UNIXTIME_MICROS: return KuduColumnSchema::UNIXTIME_MICROS;
    case kudu::DATE: return KuduColumnSchema::DATE;
    case kudu::FLOAT: return KuduColumnSchema::FLOAT;
    case kudu::DOUBLE: return KuduColumnSchema::DOUBLE;
    case kudu::VARCHAR: return KuduColumnSchema::VARCHAR;
    case kudu::STRING: return KuduColumnSchema::STRING;
    case kudu::BINARY: return KuduColumnSchema::BINARY;
    case kudu::BOOL: return KuduColumnSchema::BOOL;
    case kudu::DECIMAL32: return KuduColumnSchema::DECIMAL;
    case kudu::DECIMAL64: return KuduColumnSchema::DECIMAL;
    case kudu::DECIMAL128: return KuduColumnSchema::DECIMAL;
    default: LOG(FATAL) << "Unexpected internal data type: " << type;
  }
}

////////////////////////////////////////////////////////////
// KuduColumnTypeAttributes
////////////////////////////////////////////////////////////

KuduColumnTypeAttributes::KuduColumnTypeAttributes()
    : data_(new Data(0, 0, 0)) {
}

KuduColumnTypeAttributes::KuduColumnTypeAttributes(const KuduColumnTypeAttributes& other)
    : data_(nullptr) {
  CopyFrom(other);
}

KuduColumnTypeAttributes::KuduColumnTypeAttributes(int8_t precision, int8_t scale)
    : data_(new Data(precision, scale, 0)) {
}

KuduColumnTypeAttributes::KuduColumnTypeAttributes(uint16_t length)
    : data_(new Data(0, 0, length)) {
}

KuduColumnTypeAttributes::KuduColumnTypeAttributes(int8_t precision, int8_t scale, uint16_t length)
    : data_(new Data(precision, scale, length)) {
}

KuduColumnTypeAttributes::~KuduColumnTypeAttributes() {
  delete data_;
}

KuduColumnTypeAttributes& KuduColumnTypeAttributes::operator=(
    const KuduColumnTypeAttributes& other) {
  if (&other != this) {
    CopyFrom(other);
  }
  return *this;
}

void KuduColumnTypeAttributes::CopyFrom(const KuduColumnTypeAttributes& other) {
  delete data_;
  data_ = new Data(*other.data_);
}

int8_t KuduColumnTypeAttributes::precision() const {
  return data_->precision;
}

int8_t KuduColumnTypeAttributes::scale() const {
  return data_->scale;
}

uint16_t KuduColumnTypeAttributes::length() const {
  return data_->length;
}

Status KuduColumnStorageAttributes::StringToEncodingType(
    const string& encoding,
    KuduColumnStorageAttributes::EncodingType* type) {
  Status s;
  string encoding_uc;
  ToUpperCase(encoding, &encoding_uc);
  if (encoding_uc == "AUTO_ENCODING") {
    *type = KuduColumnStorageAttributes::AUTO_ENCODING;
  } else if (encoding_uc == "PLAIN_ENCODING") {
    *type = KuduColumnStorageAttributes::PLAIN_ENCODING;
  } else if (encoding_uc == "PREFIX_ENCODING") {
    *type = KuduColumnStorageAttributes::PREFIX_ENCODING;
  } else if (encoding_uc == "RLE") {
    *type = KuduColumnStorageAttributes::RLE;
  } else if (encoding_uc == "DICT_ENCODING") {
    *type = KuduColumnStorageAttributes::DICT_ENCODING;
  } else if (encoding_uc == "BIT_SHUFFLE") {
    *type = KuduColumnStorageAttributes::BIT_SHUFFLE;
  } else if (encoding_uc == "GROUP_VARINT") {
    *type = KuduColumnStorageAttributes::GROUP_VARINT;
  } else {
    s = Status::InvalidArgument(Substitute(
        "encoding type $0 is not supported", encoding));
  }
  return s;
}

Status KuduColumnStorageAttributes::StringToCompressionType(
    const string& compression,
    KuduColumnStorageAttributes::CompressionType* type) {
  Status s;
  string compression_uc;
  ToUpperCase(compression, &compression_uc);
  if (compression_uc == "DEFAULT_COMPRESSION") {
    *type = KuduColumnStorageAttributes::DEFAULT_COMPRESSION;
  } else if (compression_uc == "NO_COMPRESSION") {
    *type = KuduColumnStorageAttributes::NO_COMPRESSION;
  } else if (compression_uc == "SNAPPY") {
    *type = KuduColumnStorageAttributes::SNAPPY;
  } else if (compression_uc == "LZ4") {
    *type = KuduColumnStorageAttributes::LZ4;
  } else if (compression_uc == "ZLIB") {
    *type = KuduColumnStorageAttributes::ZLIB;
  } else {
    s = Status::InvalidArgument(Substitute(
        "compression type $0 is not supported", compression));
  }
  return s;
}

////////////////////////////////////////////////////////////
// KuduColumnSpec
////////////////////////////////////////////////////////////

KuduColumnSpec::KuduColumnSpec(const string& col_name)
  : data_(new Data(col_name)) {
}

KuduColumnSpec::~KuduColumnSpec() {
  delete data_;
}

KuduColumnSpec* KuduColumnSpec::Type(KuduColumnSchema::DataType type) {
  data_->type = type;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Default(KuduValue* value) {
  if (value == nullptr) return this;
  if (data_->default_val) {
    delete data_->default_val.value();
  }
  data_->default_val = value;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Compression(
    KuduColumnStorageAttributes::CompressionType compression) {
  data_->compression = compression;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Encoding(
    KuduColumnStorageAttributes::EncodingType encoding) {
  data_->encoding = encoding;
  return this;
}

KuduColumnSpec* KuduColumnSpec::BlockSize(int32_t block_size) {
  data_->block_size = block_size;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Precision(int8_t precision) {
  data_->precision = precision;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Scale(int8_t scale) {
  data_->scale = scale;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Length(uint16_t length) {
  data_->length = length;
  return this;
}

KuduColumnSpec* KuduColumnSpec::PrimaryKey() {
  data_->primary_key = true;
  return this;
}

KuduColumnSpec* KuduColumnSpec::NotNull() {
  data_->nullable = false;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Nullable() {
  data_->nullable = true;
  return this;
}

KuduColumnSpec* KuduColumnSpec::RemoveDefault() {
  data_->remove_default = true;
  return this;
}

KuduColumnSpec* KuduColumnSpec::RenameTo(const string& new_name) {
  data_->rename_to = new_name;
  return this;
}

KuduColumnSpec* KuduColumnSpec::Comment(const string& comment) {
  data_->comment = comment;
  return this;
}

Status KuduColumnSpec::ToColumnSchema(KuduColumnSchema* col) const {
  // Verify that the user isn't trying to use any methods that
  // don't make sense for CREATE.
  if (data_->rename_to) {
    return Status::NotSupported("cannot rename a column during CreateTable",
                                data_->name);
  }
  if (data_->remove_default) {
    return Status::NotSupported("cannot remove default during CreateTable",
                                data_->name);
  }

  if (!data_->type) {
    return Status::InvalidArgument("no type provided for column", data_->name);
  }

  switch (data_->type.value()) {
    case KuduColumnSchema::DECIMAL:
      if (!data_->precision) {
        return Status::InvalidArgument("no precision provided for decimal column", data_->name);
      }
      if (data_->precision.value() < kMinDecimalPrecision ||
          data_->precision.value() > kMaxDecimalPrecision) {
        return Status::InvalidArgument(
            strings::Substitute("precision must be between $0 and $1",
              kMinDecimalPrecision,
              kMaxDecimalPrecision), data_->name);
      }
      if (data_->scale) {
        if (data_->scale.value() < kMinDecimalScale) {
          return Status::InvalidArgument(
              strings::Substitute("scale is less than the minimum value of $0",
                kMinDecimalScale), data_->name);
        }
        if (data_->scale.value() > data_->precision.value()) {
          return Status::InvalidArgument(
              strings::Substitute("scale is greater than the precision value of",
                data_->precision.value()), data_->name);
        }
      }
      if (data_->length) {
        return Status::InvalidArgument(
            strings::Substitute("length is not applicable for column $0",
              data_->type.value()), data_->name);
      }
      break;
    case KuduColumnSchema::VARCHAR:
      if (!data_->length) {
        return Status::InvalidArgument("no length provided for VARCHAR column", data_->name);
      }
      if (data_->length.value() < kMinVarcharLength ||
          data_->length.value() > kMaxVarcharLength) {
        return Status::InvalidArgument(
            strings::Substitute("length must be between $0 and $1",
                                kMinVarcharLength,
                                kMaxVarcharLength), data_->name);
      }
      if (data_->precision) {
        return Status::InvalidArgument(
            strings::Substitute("precision is not valid on a $0 column",
                                data_->type.value()), data_->name);
      }
      if (data_->scale) {
        return Status::InvalidArgument(
            strings::Substitute("scale is not valid on a $0 column",
                                data_->type.value()), data_->name);
      }
      break;
    default:
      if (data_->precision) {
        return Status::InvalidArgument(
            strings::Substitute("precision is not valid on a $0 column",
                                data_->type.value()), data_->name);
      }
      if (data_->scale) {
        return Status::InvalidArgument(
            strings::Substitute("scale is not valid on a $0 column",
                                data_->type.value()), data_->name);
      }
      if (data_->length) {
        return Status::InvalidArgument(
            strings::Substitute("length is not valid on a $0 column",
                                data_->type.value()), data_->name);
      }
  }

  int8_t precision = data_->precision ? data_->precision.value() : 0;
  int8_t scale = data_->scale ? data_->scale.value() : kDefaultDecimalScale;
  uint16_t length = data_->length ? data_->length.value() : 0;

  KuduColumnTypeAttributes type_attrs(precision, scale, length);
  DataType internal_type = ToInternalDataType(data_->type.value(), type_attrs);
  bool nullable = data_->nullable ? data_->nullable.value() : true;

  void* default_val = nullptr;
  // TODO(unknown): distinguish between DEFAULT NULL and no default?
  if (data_->default_val) {
    ColumnTypeAttributes internal_type_attrs(precision, scale);
    RETURN_NOT_OK(data_->default_val.value()->data_->CheckTypeAndGetPointer(
        data_->name, internal_type, internal_type_attrs,  &default_val));
  }

  // Encoding and compression.
  KuduColumnStorageAttributes::EncodingType encoding = data_->encoding ?
      data_->encoding.value() : KuduColumnStorageAttributes::AUTO_ENCODING;
  KuduColumnStorageAttributes::CompressionType compression = data_->compression ?
      data_->compression.value() : KuduColumnStorageAttributes::DEFAULT_COMPRESSION;

  // BlockSize: '0' signifies server-side default.
  int32_t block_size = data_->block_size ? data_->block_size.value() : 0;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  *col = KuduColumnSchema(data_->name, data_->type.value(), nullable,
                          default_val,
                          KuduColumnStorageAttributes(encoding, compression, block_size),
                          type_attrs,
                          data_->comment ? data_->comment.value() : "");
#pragma GCC diagnostic pop

  return Status::OK();
}

Status KuduColumnSpec::ToColumnSchemaDelta(ColumnSchemaDelta* col_delta) const {
  if (data_->type) {
    return Status::InvalidArgument("type provided for column schema delta", data_->name);
  }
  if (data_->nullable) {
    return Status::InvalidArgument("nullability provided for column schema delta", data_->name);
  }
  if (data_->primary_key) {
    return Status::InvalidArgument("primary key set for column schema delta", data_->name);
  }

  if (data_->remove_default && data_->default_val) {
    return Status::InvalidArgument("new default set but default also removed", data_->name);
  }

  if (data_->default_val) {
    col_delta->default_value = DefaultValueAsSlice();
  }

  if (data_->remove_default) {
    col_delta->remove_default = true;
  }

  if (data_->encoding) {
    col_delta->encoding = ToInternalEncodingType(data_->encoding.value());
  }

  if (data_->compression) {
    col_delta->compression = ToInternalCompressionType(data_->compression.value());
  }

  col_delta->new_name = std::move(data_->rename_to);
  col_delta->cfile_block_size = std::move(data_->block_size);
  col_delta->new_comment = std::move(data_->comment);
  return Status::OK();
}

Slice KuduColumnSpec::DefaultValueAsSlice() const {
  if (!data_->default_val) {
    return Slice();
  }
  return data_->default_val.value()->data_->GetSlice();
}

////////////////////////////////////////////////////////////
// KuduSchemaBuilder
////////////////////////////////////////////////////////////

class KuduSchemaBuilder::Data {
 public:
  Data() {
  }

  ~Data() {
    // Rather than delete the specs here, we have to do it in
    // ~KuduSchemaBuilder(), to avoid a circular dependency in the
    // headers declaring friend classes with nested classes.
  }

  boost::optional<vector<string>> key_col_names;
  vector<KuduColumnSpec*> specs;
};

KuduSchemaBuilder::KuduSchemaBuilder()
  : data_(new Data()) {
}

KuduSchemaBuilder::~KuduSchemaBuilder() {
  for (KuduColumnSpec* spec : data_->specs) {
    // Can't use STLDeleteElements because KuduSchemaBuilder
    // is a friend of KuduColumnSpec in order to access its destructor.
    // STLDeleteElements is a free function and therefore can't access it.
    delete spec;
  }
  delete data_;
}

KuduColumnSpec* KuduSchemaBuilder::AddColumn(const string& name) {
  auto c = new KuduColumnSpec(name);
  data_->specs.push_back(c);
  return c;
}

KuduSchemaBuilder* KuduSchemaBuilder::SetPrimaryKey(
    const vector<string>& key_col_names) {
  data_->key_col_names = key_col_names;
  return this;
}

Status KuduSchemaBuilder::Build(KuduSchema* schema) {
  vector<KuduColumnSchema> cols;
  cols.resize(data_->specs.size(), KuduColumnSchema());
  for (int i = 0; i < cols.size(); i++) {
    RETURN_NOT_OK(data_->specs[i]->ToColumnSchema(&cols[i]));
  }

  int num_key_cols;

  if (!data_->key_col_names) {
    // If they didn't explicitly pass the column names for key,
    // then they should have set it on exactly one column.
    int single_key_col_idx = -1;
    for (int i = 0; i < cols.size(); i++) {
      if (data_->specs[i]->data_->primary_key) {
        if (single_key_col_idx != -1) {
          return Status::InvalidArgument("multiple columns specified for primary key",
                                         Substitute("$0, $1",
                                                    cols[single_key_col_idx].name(),
                                                    cols[i].name()));
        }
        single_key_col_idx = i;
      }
    }

    if (single_key_col_idx == -1) {
      return Status::InvalidArgument("no primary key specified");
    }

    // TODO: eventually allow primary keys which aren't the first column
    if (single_key_col_idx != 0) {
      return Status::InvalidArgument("primary key column must be the first column");
    }

    num_key_cols = 1;
  } else {
    // Build a map from name to index of all of the columns.
    unordered_map<string, int> name_to_idx_map;
    int i = 0;
    for (KuduColumnSpec* spec : data_->specs) {
      // If they did pass the key column names, then we should not have explicitly
      // set it on any columns.
      if (spec->data_->primary_key) {
        return Status::InvalidArgument("primary key specified by both SetPrimaryKey() and on a "
                                       "specific column", spec->data_->name);
      }
      // If we have a duplicate column name, the Schema::Reset() will catch it later,
      // anyway.
      name_to_idx_map[spec->data_->name] = i++;
    }

    // Convert the key column names to a set of indexes.
    vector<int> key_col_indexes;
    for (const string& key_col_name : data_->key_col_names.value()) {
      int idx;
      if (!FindCopy(name_to_idx_map, key_col_name, &idx)) {
        return Status::InvalidArgument("primary key column not defined", key_col_name);
      }
      key_col_indexes.push_back(idx);
    }

    // Currently we require that the key columns be contiguous at the front
    // of the schema. We'll lift this restriction later -- hence the more
    // flexible user-facing API.
    for (int i = 0; i < key_col_indexes.size(); i++) {
      if (key_col_indexes[i] != i) {
        return Status::InvalidArgument("primary key columns must be listed first in the schema",
                                       data_->key_col_names.value()[i]);
      }
    }

    num_key_cols = key_col_indexes.size();
  }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  RETURN_NOT_OK(schema->Reset(cols, num_key_cols));
#pragma GCC diagnostic pop

  return Status::OK();
}


////////////////////////////////////////////////////////////
// KuduColumnSchema
////////////////////////////////////////////////////////////

string KuduColumnSchema::DataTypeToString(DataType type) {
  switch (type) {
    case INT8:
      return "INT8";
    case INT16:
      return "INT16";
    case INT32:
      return "INT32";
    case INT64:
      return "INT64";
    case STRING:
      return "STRING";
    case BOOL:
      return "BOOL";
    case FLOAT:
      return "FLOAT";
    case DOUBLE:
      return "DOUBLE";
    case BINARY:
      return "BINARY";
    case UNIXTIME_MICROS:
      return "UNIXTIME_MICROS";
    case DATE:
      return "DATE";
    case DECIMAL:
      return "DECIMAL";
    case VARCHAR:
      return "VARCHAR";
  }
  LOG(FATAL) << "Unhandled type " << type;
}

 Status KuduColumnSchema::StringToDataType(
      const string& type_str, KuduColumnSchema::DataType* type) {
  Status s;
  string type_uc;
  ToUpperCase(type_str, &type_uc);
  if (type_uc == "INT8") {
    *type = INT8;
  } else if (type_uc == "INT16") {
    *type = INT16;
  } else if (type_uc == "INT32") {
    *type = INT32;
  } else if (type_uc == "INT64") {
    *type = INT64;
  } else if (type_uc == "STRING") {
    *type = STRING;
  } else if (type_uc == "BOOL") {
    *type = BOOL;
  } else if (type_uc == "FLOAT") {
    *type = FLOAT;
  } else if (type_uc == "DOUBLE") {
    *type = DOUBLE;
  } else if (type_uc == "BINARY") {
    *type = BINARY;
  } else if (type_uc == "UNIXTIME_MICROS") {
    *type = UNIXTIME_MICROS;
  } else if (type_uc == "DECIMAL") {
    *type = DECIMAL;
  } else if (type_uc == "VARCHAR") {
    *type = VARCHAR;
  } else if (type_uc == "DATE") {
    *type = DATE;
  } else {
    s = Status::InvalidArgument(Substitute(
        "data type $0 is not supported", type_str));
  }
  return s;
}

KuduColumnSchema::KuduColumnSchema(const string &name,
                                   DataType type,
                                   bool is_nullable,
                                   const void* default_value,
                                   const KuduColumnStorageAttributes& storage_attributes,
                                   const KuduColumnTypeAttributes& type_attributes,
                                   const string& comment) {
  ColumnStorageAttributes attr_private;
  attr_private.encoding = ToInternalEncodingType(storage_attributes.encoding());
  attr_private.compression = ToInternalCompressionType(
      storage_attributes.compression());
  ColumnTypeAttributes type_attr_private;
  type_attr_private.precision = type_attributes.precision();
  type_attr_private.scale = type_attributes.scale();
  type_attr_private.length = type_attributes.length();
  col_ = new ColumnSchema(name, ToInternalDataType(type, type_attributes),
                          is_nullable,
                          default_value, default_value, attr_private,
                          type_attr_private, comment);
}

KuduColumnSchema::KuduColumnSchema(const KuduColumnSchema& other)
  : col_(nullptr) {
  CopyFrom(other);
}

KuduColumnSchema::KuduColumnSchema() : col_(nullptr) {
}

KuduColumnSchema::~KuduColumnSchema() {
  delete col_;
}

KuduColumnSchema& KuduColumnSchema::operator=(const KuduColumnSchema& other) {
  if (&other != this) {
    CopyFrom(other);
  }
  return *this;
}

void KuduColumnSchema::CopyFrom(const KuduColumnSchema& other) {
  delete col_;
  if (other.col_) {
    col_ = new ColumnSchema(*other.col_);
  } else {
    col_ = nullptr;
  }
}

bool KuduColumnSchema::Equals(const KuduColumnSchema& other) const {
  return this == &other ||
    col_ == other.col_ ||
    (col_ != nullptr && col_->Equals(*other.col_, ColumnSchema::COMPARE_ALL));
}

const string& KuduColumnSchema::name() const {
  return DCHECK_NOTNULL(col_)->name();
}

bool KuduColumnSchema::is_nullable() const {
  return DCHECK_NOTNULL(col_)->is_nullable();
}

KuduColumnSchema::DataType KuduColumnSchema::type() const {
  return FromInternalDataType(DCHECK_NOTNULL(col_)->type_info()->type());
}

KuduColumnTypeAttributes KuduColumnSchema::type_attributes() const {
  ColumnTypeAttributes type_attributes = DCHECK_NOTNULL(col_)->type_attributes();
  return KuduColumnTypeAttributes(type_attributes.precision, type_attributes.scale,
                                  type_attributes.length);
}

const string& KuduColumnSchema::comment() const {
  return DCHECK_NOTNULL(col_)->comment();
}

////////////////////////////////////////////////////////////
// KuduSchema
////////////////////////////////////////////////////////////

KuduSchema::KuduSchema()
  : schema_(nullptr) {
}

KuduSchema::KuduSchema(const KuduSchema& other)
  : schema_(nullptr) {
  CopyFrom(other);
}

KuduSchema::KuduSchema(const Schema& schema)
  : schema_(new Schema(schema)) {
}

KuduSchema::KuduSchema(Schema&& schema)
  : schema_(new Schema(schema)) {
}

KuduSchema::~KuduSchema() {
  delete schema_;
}

KuduSchema& KuduSchema::operator=(const KuduSchema& other) {
  if (&other != this) {
    CopyFrom(other);
  }
  return *this;
}

void KuduSchema::CopyFrom(const KuduSchema& other) {
  delete schema_;
  schema_ = new Schema(*other.schema_);
}

Status KuduSchema::Reset(const vector<KuduColumnSchema>& columns, int key_columns) {
  vector<ColumnSchema> cols_private;
  cols_private.reserve(columns.size());
  for (const auto& col : columns) {
    cols_private.emplace_back(*col.col_);
  }
  unique_ptr<Schema> new_schema(new Schema());
  RETURN_NOT_OK(new_schema->Reset(cols_private, key_columns));

  delete schema_;
  schema_ = new_schema.release();
  return Status::OK();
}

bool KuduSchema::Equals(const KuduSchema& other) const {
  return this == &other ||
      (schema_ && other.schema_ && schema_->Equals(*other.schema_));
}

KuduColumnSchema KuduSchema::Column(size_t idx) const {
  const ColumnSchema& col = schema_->column(idx);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  KuduColumnStorageAttributes attrs(FromInternalEncodingType(col.attributes().encoding),
                                    FromInternalCompressionType(col.attributes().compression));
#pragma GCC diagnostic pop
  KuduColumnTypeAttributes type_attrs(col.type_attributes().precision, col.type_attributes().scale,
                                      col.type_attributes().length);
  return KuduColumnSchema(col.name(), FromInternalDataType(col.type_info()->type()),
                          col.is_nullable(), col.read_default_value(),
                          attrs, type_attrs, col.comment());
}

bool KuduSchema::HasColumn(const std::string& col_name, KuduColumnSchema* col_schema) const {
  int idx = schema_->find_column(col_name);
  if (idx == Schema::kColumnNotFound) {
    return false;
  }
  *col_schema = Column(idx);
  return true;
}

KuduPartialRow* KuduSchema::NewRow() const {
  return new KuduPartialRow(schema_);
}

size_t KuduSchema::num_columns() const {
  return schema_->num_columns();
}

size_t KuduSchema::num_key_columns() const {
  return schema_->num_key_columns();
}

void KuduSchema::GetPrimaryKeyColumnIndexes(vector<int>* indexes) const {
  indexes->clear();
  indexes->resize(num_key_columns());
  for (int i = 0; i < num_key_columns(); i++) {
    (*indexes)[i] = i;
  }
}

string KuduSchema::ToString() const {
  return schema_ ? schema_->ToString(FLAGS_show_attributes ?
                                     Schema::ToStringMode::WITH_COLUMN_ATTRIBUTES
                                     : Schema::ToStringMode::BASE_INFO)
                 : "()";
}

KuduSchema KuduSchema::FromSchema(const Schema& schema) {
  return KuduSchema(schema.CopyWithoutColumnIds());
}

Schema KuduSchema::ToSchema(const KuduSchema& kudu_schema) {
  return Schema(*kudu_schema.schema_);
}

} // namespace client
} // namespace kudu
