// 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/common/partial_row.h"

#include <cstring>
#include <ostream>
#include <string>
#include <utility>

#include <glog/logging.h>

#include "kudu/common/common.pb.h"
#include "kudu/common/key_encoder.h"
#include "kudu/common/row.h"
#include "kudu/common/schema.h"
#include "kudu/common/types.h"
#include "kudu/gutil/port.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/util/bitmap.h"
#include "kudu/util/char_util.h"
#include "kudu/util/decimal_util.h"
#include "kudu/util/int128.h"
#include "kudu/util/logging.h"
#ifndef NDEBUG
#include "kudu/util/memory/overwrite.h"
#endif
#include "kudu/util/status.h"

using std::string;
using strings::Substitute;

namespace kudu {

KuduPartialRow::KuduPartialRow(const Schema* schema)
  : schema_(schema) {
  DCHECK(schema_->initialized());
  size_t column_bitmap_size = BitmapSize(schema_->num_columns());
  size_t row_size = ContiguousRowHelper::row_size(*schema);

  auto dst = new uint8_t[2 * column_bitmap_size + row_size];
  isset_bitmap_ = dst;
  owned_strings_bitmap_ = isset_bitmap_ + column_bitmap_size;

  memset(isset_bitmap_, 0, 2 * column_bitmap_size);

  row_data_ = owned_strings_bitmap_ + column_bitmap_size;
#ifndef NDEBUG
  OverwriteWithPattern(reinterpret_cast<char*>(row_data_),
                       row_size, "NEWNEWNEWNEWNEW");
#endif
  ContiguousRowHelper::InitNullsBitmap(
    *schema_, row_data_, ContiguousRowHelper::null_bitmap_size(*schema_));
}

KuduPartialRow::~KuduPartialRow() {
  DeallocateOwnedStrings();
  // Both the row data and bitmap came from the same allocation.
  // The bitmap is at the start of it.
  delete [] isset_bitmap_;
}

KuduPartialRow::KuduPartialRow(const KuduPartialRow& other)
    : schema_(other.schema_) {
  size_t column_bitmap_size = BitmapSize(schema_->num_columns());
  size_t row_size = ContiguousRowHelper::row_size(*schema_);

  size_t len = 2 * column_bitmap_size + row_size;
  isset_bitmap_ = new uint8_t[len];
  owned_strings_bitmap_ = isset_bitmap_ + column_bitmap_size;
  row_data_ = owned_strings_bitmap_ + column_bitmap_size;

  // Copy all bitmaps and row data.
  memcpy(isset_bitmap_, other.isset_bitmap_, len);

  // Copy owned strings.
  for (int col_idx = 0; col_idx < schema_->num_columns(); col_idx++) {
    if (BitmapTest(owned_strings_bitmap_, col_idx)) {
      ContiguousRow row(schema_, row_data_);
      Slice* slice = reinterpret_cast<Slice*>(row.mutable_cell_ptr(col_idx));
      auto data = new uint8_t[slice->size()];
      slice->relocate(data);
    }
  }
}

KuduPartialRow& KuduPartialRow::operator=(KuduPartialRow other) {
  std::swap(schema_, other.schema_);
  std::swap(isset_bitmap_, other.isset_bitmap_);
  std::swap(owned_strings_bitmap_, other.owned_strings_bitmap_);
  std::swap(row_data_, other.row_data_);
  return *this;
}

template<typename T>
Status KuduPartialRow::Set(const Slice& col_name,
                           const typename T::cpp_type& val,
                           bool owned) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return Set<T>(col_idx, val, owned);
}

template<typename T>
Status KuduPartialRow::Set(int col_idx,
                           const typename T::cpp_type& val,
                           bool owned) {
  const ColumnSchema& col = schema_->column(col_idx);
  if (PREDICT_FALSE(col.type_info()->type() != T::type)) {
    // TODO: at some point we could allow type coercion here.
    return Status::InvalidArgument(
      Substitute("invalid type $0 provided for column '$1' (expected $2)",
                 T::name(),
                 col.name(), col.type_info()->name()));
  }

  ContiguousRow row(schema_, row_data_);

  // If we're replacing an existing STRING/BINARY value, deallocate the old value.
  if (T::physical_type == BINARY) DeallocateStringIfSet(col_idx, col);

  // Mark the column as set.
  BitmapSet(isset_bitmap_, col_idx);

  if (col.is_nullable()) {
    row.set_null(col_idx, false);
  }

  ContiguousRowCell<ContiguousRow> dst(&row, col_idx);
  memcpy(dst.mutable_ptr(), &val, sizeof(val));
  if (owned) {
    BitmapSet(owned_strings_bitmap_, col_idx);
  }
  return Status::OK();
}

Status KuduPartialRow::Set(int32_t column_idx, const uint8_t* val) {
  const ColumnSchema& column_schema = schema()->column(column_idx);

  switch (column_schema.type_info()->type()) {
    case BOOL: {
      RETURN_NOT_OK(SetBool(column_idx, *reinterpret_cast<const bool*>(val)));
      break;
    }
    case INT8: {
      RETURN_NOT_OK(SetInt8(column_idx, *reinterpret_cast<const int8_t*>(val)));
      break;
    }
    case INT16: {
      RETURN_NOT_OK(SetInt16(column_idx, *reinterpret_cast<const int16_t*>(val)));
      break;
    }
    case INT32: {
      RETURN_NOT_OK(SetInt32(column_idx, *reinterpret_cast<const int32_t*>(val)));
      break;
    }
    case INT64: {
      RETURN_NOT_OK(SetInt64(column_idx, *reinterpret_cast<const int64_t*>(val)));
      break;
    }
    case FLOAT: {
      RETURN_NOT_OK(SetFloat(column_idx, *reinterpret_cast<const float*>(val)));
      break;
    }
    case DOUBLE: {
      RETURN_NOT_OK(SetDouble(column_idx, *reinterpret_cast<const double*>(val)));
      break;
    }
    case STRING: {
      // TODO(todd) Is reinterpret_cast unsafe here?
      RETURN_NOT_OK(SetStringCopy(column_idx, *reinterpret_cast<const Slice*>(val)));
      break;
    }
    case BINARY: {
      // TODO(todd) Is reinterpret_cast unsafe here?
      RETURN_NOT_OK(SetBinaryCopy(column_idx, *reinterpret_cast<const Slice*>(val)));
      break;
    }
    case VARCHAR: {
      RETURN_NOT_OK(SetVarchar(column_idx, *reinterpret_cast<const Slice*>(val)));
      break;
    }
    case UNIXTIME_MICROS: {
      RETURN_NOT_OK(SetUnixTimeMicros(column_idx, *reinterpret_cast<const int64_t*>(val)));
      break;
    }
    case DECIMAL32: {
      RETURN_NOT_OK(Set<TypeTraits<DECIMAL32> >(column_idx,
                                                *reinterpret_cast<const int32_t*>(val)));
      break;
    }
    case DECIMAL64: {
      RETURN_NOT_OK(Set<TypeTraits<DECIMAL64> >(column_idx,
                                                *reinterpret_cast<const int64_t*>(val)));
      break;
    }
    case DECIMAL128: {
      RETURN_NOT_OK(Set<TypeTraits<DECIMAL128>>(column_idx, UnalignedLoad<int128_t>(val)));
      break;
    }
    default: {
      return Status::InvalidArgument("Unknown column type in schema",
                                     column_schema.ToString());
    }
  }
  return Status::OK();
}

void KuduPartialRow::DeallocateStringIfSet(int col_idx, const ColumnSchema& col) {
  if (BitmapTest(owned_strings_bitmap_, col_idx)) {
    ContiguousRow row(schema_, row_data_);
    const Slice* dst;
    switch (col.type_info()->type()) {
      case BINARY:
        dst = schema_->ExtractColumnFromRow<BINARY>(row, col_idx);
        break;
      case VARCHAR:
        dst = schema_->ExtractColumnFromRow<VARCHAR>(row, col_idx);
        break;
      case STRING:
        dst = schema_->ExtractColumnFromRow<STRING>(row, col_idx);
        break;
      default:
        LOG(FATAL) << "Unexpected type " << col.type_info()->type();
        break;
    }
    delete [] dst->data();
    BitmapClear(owned_strings_bitmap_, col_idx);
  }
}

void KuduPartialRow::DeallocateOwnedStrings() {
  for (int i = 0; i < schema_->num_columns(); i++) {
    DeallocateStringIfSet(i, schema_->column(i));
  }
}

//------------------------------------------------------------
// Setters
//------------------------------------------------------------

Status KuduPartialRow::SetBool(const Slice& col_name, bool val) {
  return Set<TypeTraits<BOOL> >(col_name, val);
}
Status KuduPartialRow::SetInt8(const Slice& col_name, int8_t val) {
  return Set<TypeTraits<INT8> >(col_name, val);
}
Status KuduPartialRow::SetInt16(const Slice& col_name, int16_t val) {
  return Set<TypeTraits<INT16> >(col_name, val);
}
Status KuduPartialRow::SetInt32(const Slice& col_name, int32_t val) {
  return Set<TypeTraits<INT32> >(col_name, val);
}
Status KuduPartialRow::SetInt64(const Slice& col_name, int64_t val) {
  return Set<TypeTraits<INT64> >(col_name, val);
}
Status KuduPartialRow::SetUnixTimeMicros(const Slice& col_name, int64_t val) {
  return Set<TypeTraits<UNIXTIME_MICROS> >(col_name, val);
}
Status KuduPartialRow::SetFloat(const Slice& col_name, float val) {
  return Set<TypeTraits<FLOAT> >(col_name, val);
}
Status KuduPartialRow::SetDouble(const Slice& col_name, double val) {
  return Set<TypeTraits<DOUBLE> >(col_name, val);
}
Status KuduPartialRow::SetUnscaledDecimal(const Slice& col_name, int128_t val) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return SetUnscaledDecimal(col_idx, val);
}
Status KuduPartialRow::SetBool(int col_idx, bool val) {
  return Set<TypeTraits<BOOL> >(col_idx, val);
}
Status KuduPartialRow::SetInt8(int col_idx, int8_t val) {
  return Set<TypeTraits<INT8> >(col_idx, val);
}
Status KuduPartialRow::SetInt16(int col_idx, int16_t val) {
  return Set<TypeTraits<INT16> >(col_idx, val);
}
Status KuduPartialRow::SetInt32(int col_idx, int32_t val) {
  return Set<TypeTraits<INT32> >(col_idx, val);
}
Status KuduPartialRow::SetInt64(int col_idx, int64_t val) {
  return Set<TypeTraits<INT64> >(col_idx, val);
}
Status KuduPartialRow::SetUnixTimeMicros(int col_idx, int64_t val) {
  return Set<TypeTraits<UNIXTIME_MICROS> >(col_idx, val);
}
Status KuduPartialRow::SetFloat(int col_idx, float val) {
  return Set<TypeTraits<FLOAT> >(col_idx, val);
}
Status KuduPartialRow::SetDouble(int col_idx, double val) {
  return Set<TypeTraits<DOUBLE> >(col_idx, val);
}

Status CheckDecimalValueInRange(ColumnSchema col, int128_t val) {
  int128_t max_val = MaxUnscaledDecimal(col.type_attributes().precision);
  int128_t min_val = -max_val;
  if (val < min_val || val > max_val) {
    return Status::InvalidArgument(
        Substitute("value $0 out of range for decimal column '$1'",
                   DecimalToString(val, col.type_attributes().scale), col.name()));
  }
  return Status::OK();
}

Status KuduPartialRow::SetUnscaledDecimal(int col_idx, int128_t val) {
  const ColumnSchema& col = schema_->column(col_idx);
  const DataType col_type = col.type_info()->type();
  switch (col_type) {
    case DECIMAL32:
      RETURN_NOT_OK(CheckDecimalValueInRange(col, val));
      return Set<TypeTraits<DECIMAL32> >(col_idx, static_cast<int32_t>(val));
    case DECIMAL64:
      RETURN_NOT_OK(CheckDecimalValueInRange(col, val));
      return Set<TypeTraits<DECIMAL64> >(col_idx, static_cast<int64_t>(val));
    case DECIMAL128:
      RETURN_NOT_OK(CheckDecimalValueInRange(col, val));
      return Set<TypeTraits<DECIMAL128> >(col_idx, static_cast<int128_t>(val));
    default:
      return Status::InvalidArgument(
          Substitute("invalid type $0 provided for column '$1' (expected decimal)",
                     col.type_info()->name(), col.name()));
  }
}

Status KuduPartialRow::SetBinary(const Slice& col_name, const Slice& val) {
  return SetBinaryCopy(col_name, val);
}
Status KuduPartialRow::SetString(const Slice& col_name, const Slice& val) {
  return SetStringCopy(col_name, val);
}
Status KuduPartialRow::SetVarchar(const Slice& col_name, const Slice& val) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return SetVarchar(col_idx, val);
}

Status KuduPartialRow::SetBinary(int col_idx, const Slice& val) {
  return SetBinaryCopy(col_idx, val);
}
Status KuduPartialRow::SetString(int col_idx, const Slice& val) {
  return SetStringCopy(col_idx, val);
}
Status KuduPartialRow::SetVarchar(int col_idx, const Slice& val) {
  return SetSliceCopy<TypeTraits<VARCHAR> >(col_idx, val);
}

Status KuduPartialRow::SetBinaryCopy(const Slice& col_name, const Slice& val) {
  return SetSliceCopy<TypeTraits<BINARY> >(col_name, val);
}
Status KuduPartialRow::SetStringCopy(const Slice& col_name, const Slice& val) {
  return SetSliceCopy<TypeTraits<STRING> >(col_name, val);
}
Status KuduPartialRow::SetBinaryCopy(int col_idx, const Slice& val) {
  return SetSliceCopy<TypeTraits<BINARY> >(col_idx, val);
}
Status KuduPartialRow::SetStringCopy(int col_idx, const Slice& val) {
  return SetSliceCopy<TypeTraits<STRING> >(col_idx, val);
}

Status KuduPartialRow::SetBinaryNoCopy(const Slice& col_name, const Slice& val) {
  return Set<TypeTraits<BINARY> >(col_name, val, false);
}
Status KuduPartialRow::SetStringNoCopy(const Slice& col_name, const Slice& val) {
  return Set<TypeTraits<STRING> >(col_name, val, false);
}
Status KuduPartialRow::SetBinaryNoCopy(int col_idx, const Slice& val) {
  return Set<TypeTraits<BINARY> >(col_idx, val, false);
}
Status KuduPartialRow::SetStringNoCopy(int col_idx, const Slice& val) {
  return Set<TypeTraits<STRING> >(col_idx, val, false);
}

Status KuduPartialRow::SetVarcharNoCopyUnsafe(const Slice& col_name, const Slice& val) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return SetVarcharNoCopyUnsafe(col_idx, val);
}

Status KuduPartialRow::SetVarcharNoCopyUnsafe(int col_idx, const Slice& val) {
  auto col = schema_->column(col_idx);
  if (val.size() > col.type_attributes().length * 4) {
    return Status::InvalidArgument(
        Substitute("Value too long, limit is $0 characters",
                   col.type_attributes().length));
  }
  return Set<TypeTraits<VARCHAR> >(col_idx, val);
}

template<typename T>
Status KuduPartialRow::SetSliceCopy(const Slice& col_name, const Slice& val) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return SetSliceCopy<T>(col_idx, val);
}

template<typename T>
Status KuduPartialRow::SetSliceCopy(int col_idx, const Slice& val) {
  auto col = schema_->column(col_idx);
  Slice relocated_val;
  switch (T::type) {
    case VARCHAR:
      relocated_val = UTF8Truncate(val, col.type_attributes().length);
      break;
    case STRING:
    case BINARY:
      auto relocated = new uint8_t[val.size()];
      memcpy(relocated, val.data(), val.size());
      relocated_val = Slice(relocated, val.size());
      break;
  }
  Status s = Set<T>(col_idx, relocated_val, true);
  if (!s.ok()) {
    delete [] relocated_val.data();
  }
  return s;
}

Status KuduPartialRow::SetNull(const Slice& col_name) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return SetNull(col_idx);
}

Status KuduPartialRow::SetNull(int col_idx) {
  const ColumnSchema& col = schema_->column(col_idx);
  if (PREDICT_FALSE(!col.is_nullable())) {
    return Status::InvalidArgument("column not nullable", col.ToString());
  }

  if (col.type_info()->physical_type() == BINARY) DeallocateStringIfSet(col_idx, col);

  ContiguousRow row(schema_, row_data_);
  row.set_null(col_idx, true);

  // Mark the column as set.
  BitmapSet(isset_bitmap_, col_idx);
  return Status::OK();
}

Status KuduPartialRow::Unset(const Slice& col_name) {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return Unset(col_idx);
}

Status KuduPartialRow::Unset(int col_idx) {
  const ColumnSchema& col = schema_->column(col_idx);
  if (col.type_info()->physical_type() == BINARY) DeallocateStringIfSet(col_idx, col);
  BitmapClear(isset_bitmap_, col_idx);
  return Status::OK();
}

//------------------------------------------------------------
// Template instantiations: We instantiate all possible templates to avoid linker issues.
// see: https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
// TODO We can probably remove this when we move to c++11 and can use "extern template"
//------------------------------------------------------------

template
Status KuduPartialRow::SetSliceCopy<TypeTraits<STRING> >(int col_idx, const Slice& val);

template
Status KuduPartialRow::SetSliceCopy<TypeTraits<BINARY> >(int col_idx, const Slice& val);

template
Status KuduPartialRow::SetSliceCopy<TypeTraits<STRING> >(const Slice& col_name, const Slice& val);

template
Status KuduPartialRow::SetSliceCopy<TypeTraits<BINARY> >(const Slice& col_name, const Slice& val);

template
Status KuduPartialRow::Set<TypeTraits<INT8> >(int col_idx,
                                              const TypeTraits<INT8>::cpp_type& val,
                                              bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT16> >(int col_idx,
                                               const TypeTraits<INT16>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT32> >(int col_idx,
                                               const TypeTraits<INT32>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT64> >(int col_idx,
                                               const TypeTraits<INT64>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT128> >(int col_idx,
                                               const TypeTraits<INT128>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<UNIXTIME_MICROS> >(
    int col_idx,
    const TypeTraits<UNIXTIME_MICROS>::cpp_type& val,
    bool owned);

template
Status KuduPartialRow::Set<TypeTraits<STRING> >(int col_idx,
                                                const TypeTraits<STRING>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<BINARY> >(int col_idx,
                                                const TypeTraits<BINARY>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<FLOAT> >(int col_idx,
                                               const TypeTraits<FLOAT>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DOUBLE> >(int col_idx,
                                                const TypeTraits<DOUBLE>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<BOOL> >(int col_idx,
                                              const TypeTraits<BOOL>::cpp_type& val,
                                              bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DECIMAL32> >(int col_idx,
                                                   const TypeTraits<DECIMAL32>::cpp_type& val,
                                                   bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DECIMAL64> >(int col_idx,
                                                   const TypeTraits<DECIMAL64>::cpp_type& val,
                                                   bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DECIMAL128> >(int col_idx,
                                                    const TypeTraits<DECIMAL128>::cpp_type& val,
                                                    bool owned);


template
Status KuduPartialRow::Set<TypeTraits<INT8> >(const Slice& col_name,
                                              const TypeTraits<INT8>::cpp_type& val,
                                              bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT16> >(const Slice& col_name,
                                               const TypeTraits<INT16>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT32> >(const Slice& col_name,
                                               const TypeTraits<INT32>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT64> >(const Slice& col_name,
                                               const TypeTraits<INT64>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<INT128> >(const Slice& col_name,
                                                const TypeTraits<INT128>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<UNIXTIME_MICROS> >(
    const Slice& col_name,
    const TypeTraits<UNIXTIME_MICROS>::cpp_type& val,
    bool owned);

template
Status KuduPartialRow::Set<TypeTraits<FLOAT> >(const Slice& col_name,
                                               const TypeTraits<FLOAT>::cpp_type& val,
                                               bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DOUBLE> >(const Slice& col_name,
                                                const TypeTraits<DOUBLE>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<BOOL> >(const Slice& col_name,
                                              const TypeTraits<BOOL>::cpp_type& val,
                                              bool owned);

template
Status KuduPartialRow::Set<TypeTraits<STRING> >(const Slice& col_name,
                                                const TypeTraits<STRING>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<BINARY> >(const Slice& col_name,
                                                const TypeTraits<BINARY>::cpp_type& val,
                                                bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DECIMAL32> >(const Slice& col_name,
                                                   const TypeTraits<DECIMAL32>::cpp_type& val,
                                                   bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DECIMAL64> >(const Slice& col_name,
                                                   const TypeTraits<DECIMAL64>::cpp_type& val,
                                                   bool owned);

template
Status KuduPartialRow::Set<TypeTraits<DECIMAL128> >(const Slice& col_name,
                                                    const TypeTraits<DECIMAL128>::cpp_type& val,
                                                    bool owned);

//------------------------------------------------------------
// Getters
//------------------------------------------------------------
bool KuduPartialRow::IsColumnSet(int col_idx) const {
  DCHECK_GE(col_idx, 0);
  DCHECK_LT(col_idx, schema_->num_columns());
  return BitmapTest(isset_bitmap_, col_idx);
}

bool KuduPartialRow::IsColumnSet(const Slice& col_name) const {
  int col_idx;
  CHECK_OK(schema_->FindColumn(col_name, &col_idx));
  return IsColumnSet(col_idx);
}

bool KuduPartialRow::IsNull(int col_idx) const {
  const ColumnSchema& col = schema_->column(col_idx);
  if (!col.is_nullable()) {
    return false;
  }

  if (!IsColumnSet(col_idx)) return false;

  ContiguousRow row(schema_, row_data_);
  return row.is_null(col_idx);
}

bool KuduPartialRow::IsNull(const Slice& col_name) const {
  int col_idx;
  CHECK_OK(schema_->FindColumn(col_name, &col_idx));
  return IsNull(col_idx);
}

Status KuduPartialRow::GetBool(const Slice& col_name, bool* val) const {
  return Get<TypeTraits<BOOL> >(col_name, val);
}
Status KuduPartialRow::GetInt8(const Slice& col_name, int8_t* val) const {
  return Get<TypeTraits<INT8> >(col_name, val);
}
Status KuduPartialRow::GetInt16(const Slice& col_name, int16_t* val) const {
  return Get<TypeTraits<INT16> >(col_name, val);
}
Status KuduPartialRow::GetInt32(const Slice& col_name, int32_t* val) const {
  return Get<TypeTraits<INT32> >(col_name, val);
}
Status KuduPartialRow::GetInt64(const Slice& col_name, int64_t* val) const {
  return Get<TypeTraits<INT64> >(col_name, val);
}
Status KuduPartialRow::GetUnixTimeMicros(const Slice& col_name,
                                         int64_t* micros_since_utc_epoch) const {
  return Get<TypeTraits<UNIXTIME_MICROS> >(col_name, micros_since_utc_epoch);
}
Status KuduPartialRow::GetFloat(const Slice& col_name, float* val) const {
  return Get<TypeTraits<FLOAT> >(col_name, val);
}
Status KuduPartialRow::GetDouble(const Slice& col_name, double* val) const {
  return Get<TypeTraits<DOUBLE> >(col_name, val);
}
Status KuduPartialRow::GetUnscaledDecimal(const Slice &col_name, int128_t *val) {
  // Call the const version of the function.
  return const_cast<const KuduPartialRow*>(this)->GetUnscaledDecimal(col_name, val);
}
Status KuduPartialRow::GetUnscaledDecimal(const Slice &col_name, int128_t *val) const {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return GetUnscaledDecimal(col_idx, val);
}
Status KuduPartialRow::GetString(const Slice& col_name, Slice* val) const {
  return Get<TypeTraits<STRING> >(col_name, val);
}
Status KuduPartialRow::GetBinary(const Slice& col_name, Slice* val) const {
  return Get<TypeTraits<BINARY> >(col_name, val);
}
Status KuduPartialRow::GetVarchar(const Slice& col_name, Slice* val) const {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return GetVarchar(col_idx, val);
}

Status KuduPartialRow::GetBool(int col_idx, bool* val) const {
  return Get<TypeTraits<BOOL> >(col_idx, val);
}
Status KuduPartialRow::GetInt8(int col_idx, int8_t* val) const {
  return Get<TypeTraits<INT8> >(col_idx, val);
}
Status KuduPartialRow::GetInt16(int col_idx, int16_t* val) const {
  return Get<TypeTraits<INT16> >(col_idx, val);
}
Status KuduPartialRow::GetInt32(int col_idx, int32_t* val) const {
  return Get<TypeTraits<INT32> >(col_idx, val);
}
Status KuduPartialRow::GetInt64(int col_idx, int64_t* val) const {
  return Get<TypeTraits<INT64> >(col_idx, val);
}
Status KuduPartialRow::GetUnixTimeMicros(int col_idx, int64_t* micros_since_utc_epoch) const {
  return Get<TypeTraits<UNIXTIME_MICROS> >(col_idx, micros_since_utc_epoch);
}
Status KuduPartialRow::GetFloat(int col_idx, float* val) const {
  return Get<TypeTraits<FLOAT> >(col_idx, val);
}
Status KuduPartialRow::GetDouble(int col_idx, double* val) const {
  return Get<TypeTraits<DOUBLE> >(col_idx, val);
}
Status KuduPartialRow::GetUnscaledDecimal(int col_idx, int128_t *val) {
  // Call the const version of the function.
  return const_cast<const KuduPartialRow*>(this)->GetUnscaledDecimal(col_idx, val);
}
Status KuduPartialRow::GetUnscaledDecimal(int col_idx, int128_t *val) const {
  const ColumnSchema& col = schema_->column(col_idx);
  const DataType col_type = col.type_info()->type();
  switch (col_type) {
    case DECIMAL32:
      int32_t i32_val;
      RETURN_NOT_OK(Get<TypeTraits<DECIMAL32> >(col_idx, &i32_val));
      *val = i32_val;
      return Status::OK();
    case DECIMAL64:
      int64_t i64_val;
      RETURN_NOT_OK(Get<TypeTraits<DECIMAL64> >(col_idx, &i64_val));
      *val = i64_val;
      return Status::OK();
    case DECIMAL128:
      int128_t i128_val;
      RETURN_NOT_OK(Get<TypeTraits<DECIMAL128> >(col_idx, &i128_val));
      *val = i128_val;
      return Status::OK();
    default:
      return Status::InvalidArgument(
          Substitute("invalid type $0 provided for column '$1' (expected decimal)",
                     col.type_info()->name(), col.name()));
  }
}
Status KuduPartialRow::GetString(int col_idx, Slice* val) const {
  return Get<TypeTraits<STRING> >(col_idx, val);
}
Status KuduPartialRow::GetBinary(int col_idx, Slice* val) const {
  return Get<TypeTraits<BINARY> >(col_idx, val);
}
Status KuduPartialRow::GetVarchar(int col_idx, Slice* val) const {
  return Get<TypeTraits<VARCHAR> >(col_idx, val);
}

template<typename T>
Status KuduPartialRow::Get(const Slice& col_name,
                           typename T::cpp_type* val) const {
  int col_idx;
  RETURN_NOT_OK(schema_->FindColumn(col_name, &col_idx));
  return Get<T>(col_idx, val);
}

template<typename T>
Status KuduPartialRow::Get(int col_idx, typename T::cpp_type* val) const {
  const ColumnSchema& col = schema_->column(col_idx);
  if (PREDICT_FALSE(col.type_info()->type() != T::type)) {
    // TODO: at some point we could allow type coercion here.
    return Status::InvalidArgument(
      Substitute("invalid type $0 provided for column '$1' (expected $2)",
                 T::name(),
                 col.name(), col.type_info()->name()));
  }

  if (PREDICT_FALSE(!IsColumnSet(col_idx))) {
    return Status::NotFound("column not set");
  }
  if (col.is_nullable() && IsNull(col_idx)) {
    return Status::NotFound("column is NULL");
  }

  ContiguousRow row(schema_, row_data_);
  memcpy(val, row.cell_ptr(col_idx), sizeof(*val));
  return Status::OK();
}


//------------------------------------------------------------
// Key-encoding related functions
//------------------------------------------------------------
Status KuduPartialRow::EncodeRowKey(string* encoded_key) const {
  // Currently, a row key must be fully specified.
  // TODO: allow specifying a prefix of the key, and automatically
  // fill the rest with minimum values.
  for (int i = 0; i < schema_->num_key_columns(); i++) {
    if (PREDICT_FALSE(!IsColumnSet(i))) {
      return Status::InvalidArgument("All key columns must be set",
                                     schema_->column(i).name());
    }
  }

  encoded_key->clear();
  ContiguousRow row(schema_, row_data_);

  for (int i = 0; i < schema_->num_key_columns(); i++) {
    bool is_last = i == schema_->num_key_columns() - 1;
    const TypeInfo* ti = schema_->column(i).type_info();
    GetKeyEncoder<string>(ti).Encode(row.cell_ptr(i), is_last, encoded_key);
  }

  return Status::OK();
}

string KuduPartialRow::ToEncodedRowKeyOrDie() const {
  string ret;
  CHECK_OK(EncodeRowKey(&ret));
  return ret;
}

//------------------------------------------------------------
// Utility code
//------------------------------------------------------------

bool KuduPartialRow::AllColumnsSet() const {
  return BitmapIsAllSet(isset_bitmap_, 0, schema_->num_columns());
}

bool KuduPartialRow::IsKeySet() const {
  return BitmapIsAllSet(isset_bitmap_, 0, schema_->num_key_columns());
}


std::string KuduPartialRow::ToString() const {
  ScopedDisableRedaction no_redaction;

  ContiguousRow row(schema_, row_data_);
  std::string ret;
  bool first = true;
  for (int i = 0; i < schema_->num_columns(); i++) {
    if (IsColumnSet(i)) {
      if (!first) {
        ret.append(", ");
      }
      schema_->column(i).DebugCellAppend(row.cell(i), &ret);
      first = false;
    }
  }
  return ret;
}

//------------------------------------------------------------
// Serialization/deserialization
//------------------------------------------------------------


} // namespace kudu
