/**
 * 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 <cstddef>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "gtest/gtest.h"

#include "catalog/CatalogAttribute.hpp"
#include "catalog/CatalogRelation.hpp"
#include "catalog/CatalogTypedefs.hpp"
#include "expressions/predicate/ComparisonPredicate.hpp"
#include "expressions/scalar/Scalar.hpp"
#include "expressions/scalar/ScalarAttribute.hpp"
#include "expressions/scalar/ScalarLiteral.hpp"
#include "storage/CompressedPackedRowStoreTupleStorageSubBlock.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "storage/StorageConstants.hpp"
#include "storage/StorageErrors.hpp"
#include "storage/tests/TupleStorePredicateUtil.hpp"
#include "types/CharType.hpp"
#include "types/DoubleType.hpp"
#include "types/IntType.hpp"
#include "types/LongType.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypedValue.hpp"
#include "types/TypeID.hpp"
#include "types/VarCharType.hpp"
#include "types/containers/Tuple.hpp"
#include "types/operations/comparisons/Comparison.hpp"
#include "types/operations/comparisons/ComparisonFactory.hpp"
#include "types/operations/comparisons/ComparisonID.hpp"
#include "utility/BitVector.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrMap.hpp"
#include "utility/PtrVector.hpp"
#include "utility/ScopedBuffer.hpp"

using std::numeric_limits;
using std::pair;
using std::size_t;
using std::snprintf;
using std::string;

namespace quickstep {

class CompressedPackedRowStoreTupleStorageSubBlockTest : public ::testing::TestWithParam<bool> {
 protected:
  // 3 MB is just large enough to make sure that all attributes in our schema
  // get the compression that we desire for testing.
  static const size_t kSubBlockSize = 0x300000;
  static const size_t kExpectedTupleSize = 22;

  virtual void SetUp() {
    // Create a sample relation with a variety of attribute types.
    relation_.reset(new CatalogRelation(nullptr, "TestRelation"));

    // An attribute which will be compressed by truncation to 1 byte.
    CatalogAttribute *current_attr = new CatalogAttribute(relation_.get(),
                                                          "int_attr_trunc_byte",
                                                          TypeFactory::GetType(kInt, GetParam()));
    ASSERT_EQ(0, relation_->addAttribute(current_attr));

    // A string attribute which will be dictionary-compressed as 1 byte.
    current_attr = new CatalogAttribute(relation_.get(),
                                        "char_attr_dict_byte",
                                        TypeFactory::GetType(kChar, 8, GetParam()));
    ASSERT_EQ(1, relation_->addAttribute(current_attr));

    // An attribute which will by compressed by truncation to 4 bytes.
    current_attr = new CatalogAttribute(relation_.get(),
                                        "long_attr_trunc_word",
                                        TypeFactory::GetType(kLong, GetParam()));
    ASSERT_EQ(2, relation_->addAttribute(current_attr));

    // A varchar attribute, which must be dictionary-compressed.
    current_attr = new CatalogAttribute(relation_.get(),
                                        "varchar_attr_dict_short",
                                        TypeFactory::GetType(kVarChar, 16, GetParam()));
    ASSERT_EQ(3, relation_->addAttribute(current_attr));

    // An integer attribute which will be dictionary-compressed to 2 bytes.
    current_attr = new CatalogAttribute(relation_.get(),
                                        "int_attr_dict_short",
                                        TypeFactory::GetType(kInt, GetParam()));
    ASSERT_EQ(4, relation_->addAttribute(current_attr));

    // An attribute which can't be compressed (though we will try).
    current_attr = new CatalogAttribute(relation_.get(),
                                        "int_attr_fail_compression",
                                        TypeFactory::GetType(kInt, GetParam()));
    ASSERT_EQ(5, relation_->addAttribute(current_attr));

    // An attribute which could be compressed, but which we will not attempt to
    // compress.
    current_attr = new CatalogAttribute(relation_.get(),
                                        "long_attr_no_compression",
                                        TypeFactory::GetType(kLong, GetParam()));
    ASSERT_EQ(6, relation_->addAttribute(current_attr));

    // Don't initialize the block yet. Different tests will use different
    // params.
    tuple_store_memory_.reset();
    tuple_store_description_.reset();
    tuple_store_.reset();
  }

  void initializeTupleStoreDescription() {
    tuple_store_description_.reset(new TupleStorageSubBlockDescription());
    tuple_store_description_->set_sub_block_type(TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
    for (attribute_id attr_id = 0; attr_id < 6; ++attr_id) {
      tuple_store_description_->AddExtension(
          CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id,
          attr_id);
    }
  }

  void initializeNewBlock(const size_t block_size) {
    tuple_store_memory_.reset(block_size);
    tuple_store_.reset(new CompressedPackedRowStoreTupleStorageSubBlock(*relation_,
                                                                        *tuple_store_description_,
                                                                        true,
                                                                        tuple_store_memory_.get(),
                                                                        block_size));
  }

  // Caller takes ownership of new heap-created Tuple.
  Tuple* createSampleTuple(const tuple_id tid) const {
    std::vector<TypedValue> attrs;

    // int_attr_trunc_byte - never null, since that prevents truncation.
    attrs.emplace_back(static_cast<int>(tid % numeric_limits<int8_t>::max()));

    // char_attr_dict_byte
    int char_attr_dict_byte_seed = tid % numeric_limits<int8_t>::max();
    if (GetParam() && (char_attr_dict_byte_seed % 8 == 2)) {
      attrs.emplace_back(kChar);
    } else {
      char char_buffer[8];
      int written = snprintf(char_buffer,
                             sizeof(char_buffer),
                             "%d",
                             char_attr_dict_byte_seed);
      attrs.emplace_back(CharType::InstanceNonNullable(8).makeValue(
          char_buffer,
          written + 1).ensureNotReference());
    }

    // long_attr_trunc_word - never null, since that prevents truncation.
    attrs.emplace_back(static_cast<std::int64_t>(numeric_limits<int32_t>::max() - tid));

    // varchar_attr_dict_short
    int varchar_attr_dict_short_seed = tid % numeric_limits<int16_t>::max();
    if (GetParam() && (varchar_attr_dict_short_seed % 8 == 0)) {
      attrs.emplace_back(kVarChar);
    } else {
      char varchar_buffer[8];
      int written = snprintf(varchar_buffer,
                             sizeof(varchar_buffer),
                             "%d",
                             varchar_attr_dict_short_seed);
      attrs.emplace_back(VarCharType::InstanceNonNullable(16).makeValue(
          varchar_buffer,
          written + 1).ensureNotReference());
    }

    // int_attr_dict_short
    int int_attr_dict_short_seed = tid % numeric_limits<int16_t>::max();
    if (GetParam() && (int_attr_dict_short_seed % 8 == 4)) {
      attrs.emplace_back(kInt);
    } else {
      if (int_attr_dict_short_seed & 0x1) {
        attrs.emplace_back(static_cast<int>(0x1000000 + int_attr_dict_short_seed));
      } else {
        attrs.emplace_back(static_cast<int>(-int_attr_dict_short_seed));
      }
    }

    // int_attr_fail_compression
    if (GetParam() && (tid % 8 == 6)) {
      attrs.emplace_back(kInt);
    } else {
      attrs.emplace_back(static_cast<int>(numeric_limits<int32_t>::max() - tid));
    }

    // long_attr_no_compression (could easily be truncated to one byte if we
    // actually tried).
    attrs.emplace_back(static_cast<std::int64_t>(tid % numeric_limits<int8_t>::max()));

    return new Tuple(std::move(attrs));
  }

  void fillBlockWithSampleData() {
    tuple_id current_tid = 0;
    std::unique_ptr<Tuple> current_tuple(createSampleTuple(current_tid));
    while (tuple_store_->insertTupleInBatch(*current_tuple)) {
      ++current_tid;
      current_tuple.reset(createSampleTuple(current_tid));
    }

    tuple_store_->rebuild();
  }

  int computeCompressedBlockInfoSize() const {
    CompressedBlockInfo info;

    for (attribute_id attr_id = 0;
         attr_id <= relation_->getMaxAttributeId();
         ++attr_id) {
      info.add_attribute_size(0);
      info.add_dictionary_size(0);
      info.add_uncompressed_attribute_has_nulls(false);
    }

    info.set_null_bitmap_bits(0);

    return info.ByteSize();
  }

  size_t computeTotalDictionarySize(const tuple_id num_tuples) const {
    size_t total_size = 0;

    // char_attr_dict_byte
    total_size += 2 * sizeof(std::uint32_t);
    size_t non_null_values = num_tuples < numeric_limits<int8_t>::max() ? num_tuples
                                                                        : numeric_limits<int8_t>::max();
    if (GetParam()) {
      if (non_null_values % 8 > 2) {
        non_null_values -= non_null_values / 8;
        --non_null_values;
      } else {
        non_null_values -= non_null_values / 8;
      }
    }
    total_size += non_null_values * 8;

    // varchar_attr_dict_short
    total_size += 2 * sizeof(std::uint32_t);
    non_null_values = num_tuples < numeric_limits<int16_t>::max() ? num_tuples
                                                                  : numeric_limits<int16_t>::max();
    if (GetParam()) {
      non_null_values -= non_null_values / 8;
      --non_null_values;
    }
    total_size += non_null_values * sizeof(std::uint32_t);

    if (num_tuples < 10) {
      total_size += num_tuples * 2;
    } else {
      total_size += 10 * 2;
      if (num_tuples < 100) {
        total_size += (num_tuples - 10) * 3;
      } else {
        total_size += 90 * 3;
        if (num_tuples < 1000) {
          total_size += (num_tuples - 100) * 4;
        } else {
          total_size += 900 * 4;
          if (num_tuples < 10000) {
            total_size += (num_tuples - 1000) * 5;
          } else {
            total_size += 9000 * 5;
            if (num_tuples < numeric_limits<int16_t>::max()) {
              total_size += (num_tuples - 10000) * 6;
            } else {
              total_size += (numeric_limits<int16_t>::max() - 10000) * 6;
            }
          }
        }
      }
    }

    // Go back through and subtract out nulls.
    if (GetParam()) {
      total_size -= 2;
      if (num_tuples < 10) {
        total_size -= (num_tuples / 8) * 2;
      } else {
        total_size -= 2;
        if (num_tuples < 100) {
          total_size -= ((num_tuples / 8) - 1) * 3;
        } else {
          total_size -= 11 * 3;
          if (num_tuples < 1000) {
            total_size -= ((num_tuples / 8) - 12) * 4;
          } else {
            total_size -= 112 * 4;
            if (num_tuples < 10000) {
              total_size -= ((num_tuples / 8) - 124) * 5;
            } else {
              total_size -= 1125 * 5;
              if (num_tuples < numeric_limits<int16_t>::max()) {
                total_size -= ((num_tuples / 8) - 1249) * 6;
              } else {
                total_size -= ((numeric_limits<int16_t>::max() / 8) - 1249) * 6;
              }
            }
          }
        }
      }
    }

    // int_attr_dict_short
    total_size += 2 * sizeof(std::uint32_t);
    non_null_values = num_tuples < numeric_limits<int16_t>::max() ? num_tuples
                                                                  : numeric_limits<int16_t>::max();
    if (GetParam()) {
      if (non_null_values % 8 > 4) {
        non_null_values -= non_null_values / 8;
        --non_null_values;
      } else {
        non_null_values -= non_null_values / 8;
      }
    }
    total_size += non_null_values * 4;

    return total_size;
  }

  size_t computeRequiredStorage(const tuple_id num_tuples) const {
    return sizeof(tuple_id) + sizeof(int)
           + computeCompressedBlockInfoSize()
           + computeTotalDictionarySize(num_tuples)
           + num_tuples * kExpectedTupleSize
           + GetParam() * BitVector<false>::BytesNeeded(num_tuples);
  }

  // Check that every attribute value of every tuple in tuple_store_ is as
  // expected.
  void checkBlockValues() const {
    EXPECT_FALSE(tuple_store_->isEmpty());
    EXPECT_TRUE(tuple_store_->isPacked());

    // Truncated attributes don't support untyped access. Dictionary-compressed
    // and uncompressed attributes do.
    EXPECT_FALSE(tuple_store_->supportsUntypedGetAttributeValue(0));
    EXPECT_TRUE(tuple_store_->supportsUntypedGetAttributeValue(1));
    EXPECT_FALSE(tuple_store_->supportsUntypedGetAttributeValue(2));
    EXPECT_TRUE(tuple_store_->supportsUntypedGetAttributeValue(3));
    EXPECT_TRUE(tuple_store_->supportsUntypedGetAttributeValue(4));
    EXPECT_TRUE(tuple_store_->supportsUntypedGetAttributeValue(5));
    EXPECT_TRUE(tuple_store_->supportsUntypedGetAttributeValue(6));

    // Set up some UncheckedComparators to do the equals comparison for each
    // attribute.
    PtrVector<UncheckedComparator> eq_comparators;
    for (CatalogRelation::const_iterator attr_it = relation_->begin();
         attr_it != relation_->end();
         ++attr_it) {
      eq_comparators.push_back(ComparisonFactory::GetComparison(ComparisonID::kEqual).makeUncheckedComparatorForTypes(
          attr_it->getType(), attr_it->getType()));
    }

    // Go through all of the tuples in the block and check that their values
    // are as expected.
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      std::unique_ptr<Tuple> check_tuple(createSampleTuple(tid));
      EXPECT_TRUE(tuple_store_->hasTupleWithID(tid));

      for (attribute_id attr_id = 0;
           attr_id <= relation_->getMaxAttributeId();
           ++attr_id) {
        if (GetParam() && check_tuple->getAttributeValue(attr_id).isNull()) {
          EXPECT_EQ(nullptr, tuple_store_->getAttributeValue(tid, attr_id));
          EXPECT_TRUE(tuple_store_->getAttributeValueTyped(tid, attr_id).isNull());
        } else {
          if ((attr_id != 0) && (attr_id != 2)) {
            EXPECT_TRUE(eq_comparators[attr_id].compareDataPtrs(
                check_tuple->getAttributeValue(attr_id).getDataPtr(),
                tuple_store_->getAttributeValue(tid, attr_id)));
          }

          TypedValue attr_value(tuple_store_->getAttributeValueTyped(tid, attr_id));
          EXPECT_TRUE(eq_comparators[attr_id].compareTypedValues(
              check_tuple->getAttributeValue(attr_id),
              attr_value));
        }
      }
    }
  }

  // Create a ComparisonPredicate of the form "attribute comp literal".
  template <typename AttributeType>
  Predicate* generateNumericComparisonPredicate(const ComparisonID comp,
                                                const attribute_id attribute,
                                                const typename AttributeType::cpptype literal) const {
    ScalarAttribute *scalar_attribute = new ScalarAttribute(*relation_->getAttributeById(attribute));
    ScalarLiteral *scalar_literal
        = new ScalarLiteral(AttributeType::InstanceNonNullable().makeValue(&literal),
                            AttributeType::InstanceNonNullable());
    return new ComparisonPredicate(ComparisonFactory::GetComparison(comp), scalar_attribute, scalar_literal);
  }

  Predicate* generateStringComparisonPredicate(const ComparisonID comp,
                                               const attribute_id attribute,
                                               const string &literal) const {
    ScalarAttribute *scalar_attribute = new ScalarAttribute(*relation_->getAttributeById(attribute));
    ScalarLiteral *scalar_literal = new ScalarLiteral(
        VarCharType::InstanceNonNullable(literal.size()).makeValue(
            literal.c_str(),
            literal.size() + 1).ensureNotReference(),
        VarCharType::InstanceNonNullable(literal.size()));
    return new ComparisonPredicate(ComparisonFactory::GetComparison(comp),
                                   scalar_attribute,
                                   scalar_literal);
  }

  template <typename ValueType>
  inline static bool matchExpected(const ComparisonID comp,
                                   const ValueType &left,
                                   const ValueType &right) {
    switch (comp) {
      case ComparisonID::kEqual:
        return (left == right);
      case ComparisonID::kNotEqual:
        return (left != right);
      case ComparisonID::kLess:
        return (left < right);
      case ComparisonID::kLessOrEqual:
        return (left <= right);
      case ComparisonID::kGreater:
        return (left > right);
      case ComparisonID::kGreaterOrEqual:
        return (left >= right);
      default:
        FATAL_ERROR("Unrecognized ComparisonID");
    }
  }

  void checkPredicateAttr0(const ComparisonID comp) const {
    std::unique_ptr<Predicate> predicate(
        generateNumericComparisonPredicate<IntType>(comp,
                                                    0,
                                                    numeric_limits<int8_t>::max() >> 1));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (matchExpected(comp, tid % numeric_limits<int8_t>::max(), numeric_limits<int8_t>::max() >> 1)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  void checkPredicateAttr1(const ComparisonID comp) const {
    string string_literal("50");

    std::unique_ptr<Predicate> predicate(generateStringComparisonPredicate(comp,
                                                                           1,
                                                                           string_literal));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (GetParam() && (tid % numeric_limits<int8_t>::max() % 8 == 2)) {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
        continue;
      }

      char str_buffer[8];
      snprintf(str_buffer,
               sizeof(str_buffer),
               "%d",
               (tid % numeric_limits<int8_t>::max()));
      if (matchExpected(comp, string(str_buffer), string_literal)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  void checkPredicateAttr2(const ComparisonID comp) const {
    LongType::cpptype literal_value = numeric_limits<int32_t>::max() - (tuple_store_->getMaxTupleID() >> 1);

    std::unique_ptr<Predicate> predicate(generateNumericComparisonPredicate<LongType>(comp,
                                                                                      2,
                                                                                      literal_value));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (matchExpected(comp,
                        static_cast<LongType::cpptype>(numeric_limits<int32_t>::max() - tid),
                        literal_value)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  void checkPredicateAttr3(const ComparisonID comp) const {
    string string_literal("5000");

    std::unique_ptr<Predicate> predicate(generateStringComparisonPredicate(comp,
                                                                           3,
                                                                           string_literal));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (GetParam() && (tid % numeric_limits<int16_t>::max() % 8 == 0)) {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
        continue;
      }

      char str_buffer[8];
      snprintf(str_buffer,
               sizeof(str_buffer),
               "%d",
               (tid % numeric_limits<int16_t>::max()));
      if (matchExpected(comp, string(str_buffer), string_literal)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  void checkPredicateAttr4(const ComparisonID comp) const {
    std::unique_ptr<Predicate> predicate(generateNumericComparisonPredicate<IntType>(comp,
                                                                                     4,
                                                                                     0));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (GetParam() && (tid % numeric_limits<int16_t>::max() % 8 == 4)) {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
        continue;
      }

      int expected_attr_value = (tid % numeric_limits<int16_t>::max()) & 0x1 ?
                                0x1000000 + tid % numeric_limits<int16_t>::max()
                                : -(tid % numeric_limits<int16_t>::max());
      if (matchExpected(comp, expected_attr_value, 0)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  void checkPredicateAttr5(const ComparisonID comp) const {
    int literal_value = numeric_limits<int32_t>::max() - (tuple_store_->getMaxTupleID() >> 1);

    std::unique_ptr<Predicate> predicate(generateNumericComparisonPredicate<IntType>(comp,
                                                                                     5,
                                                                                     literal_value));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (GetParam() && (tid % 8 == 6)) {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
        continue;
      }

      if (matchExpected(comp, numeric_limits<int32_t>::max() - tid, literal_value)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  void checkPredicateAttr6(const ComparisonID comp) const {
    std::unique_ptr<Predicate> predicate(
        generateNumericComparisonPredicate<LongType>(comp,
                                                     6,
                                                     numeric_limits<int8_t>::max() >> 1));
    std::unique_ptr<TupleIdSequence> matches(
        TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
    TupleIdSequence::const_iterator current_match_it = matches->begin();
    for (tuple_id tid = 0;
         tid <= tuple_store_->getMaxTupleID();
         ++tid) {
      if (matchExpected(comp, tid % numeric_limits<int8_t>::max(), numeric_limits<int8_t>::max() >> 1)) {
        ASSERT_NE(current_match_it, matches->end());
        EXPECT_EQ(tid, *current_match_it);
        ++current_match_it;
      } else {
        if (current_match_it != matches->end()) {
          EXPECT_NE(tid, *current_match_it);
        }
      }
    }
  }

  std::unique_ptr<CatalogRelation> relation_;
  ScopedBuffer tuple_store_memory_;
  std::unique_ptr<TupleStorageSubBlockDescription> tuple_store_description_;
  std::unique_ptr<CompressedPackedRowStoreTupleStorageSubBlock> tuple_store_;
};

typedef CompressedPackedRowStoreTupleStorageSubBlockTest
        CompressedPackedRowStoreTupleStorageSubBlockDeathTest;

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, DescriptionIsValidTest) {
  tuple_store_description_.reset(new TupleStorageSubBlockDescription());

  // An uninitialized description is not valid.
  EXPECT_FALSE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*relation_,
                                                                                *tuple_store_description_));

  // A description that specifies the wrong sub_block_type is not valid.
  tuple_store_description_->set_sub_block_type(TupleStorageSubBlockDescription::SPLIT_ROW_STORE);
  EXPECT_FALSE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*relation_,
                                                                                *tuple_store_description_));

  // A description which has an uncompressed variable-length attribute is not
  // valid.
  tuple_store_description_->set_sub_block_type(TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  EXPECT_FALSE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*relation_,
                                                                                *tuple_store_description_));

  // Specifying that the variable-length attribute is compressed should make
  // the description valid.
  tuple_store_description_->AddExtension(
      CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id,
      3);
  EXPECT_TRUE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*relation_,
                                                                               *tuple_store_description_));

  // Specifying a non-existent attribute for compression causes the description
  // to be invalid.
  tuple_store_description_->AddExtension(
      CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id,
      64);
  EXPECT_FALSE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*relation_,
                                                                                *tuple_store_description_));

  // A relation with a nullable attribute is OK.
  std::unique_ptr<CatalogRelation> nullable_relation(new CatalogRelation(NULL, "nullable_relation"));
  CatalogAttribute *nullable_attribute = new CatalogAttribute(nullable_relation.get(),
                                                              "nullable_attr",
                                                              TypeFactory::GetType(kInt, true));
  ASSERT_EQ(0, nullable_relation->addAttribute(nullable_attribute));
  tuple_store_description_.reset(new TupleStorageSubBlockDescription());
  tuple_store_description_->set_sub_block_type(TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  EXPECT_TRUE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*nullable_relation,
                                                                               *tuple_store_description_));

  // It's also OK if a nullable attribute is compressed.
  tuple_store_description_->AddExtension(
      CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id,
      0);
  EXPECT_TRUE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*nullable_relation,
                                                                               *tuple_store_description_));

  // The description we use for the other tests should be valid.
  initializeTupleStoreDescription();
  EXPECT_TRUE(CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid(*relation_,
                                                                               *tuple_store_description_));
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockDeathTest, ConstructWithInvalidDescriptionTest) {
  tuple_store_description_.reset(new TupleStorageSubBlockDescription());
  tuple_store_description_->set_sub_block_type(TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  EXPECT_DEATH(initializeNewBlock(kSubBlockSize), "");
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, MemoryTooSmallTest) {
  initializeTupleStoreDescription();
  // 1 byte short.
  EXPECT_THROW(initializeNewBlock(computeCompressedBlockInfoSize() + sizeof(tuple_id) + sizeof(int) - 1),
               BlockMemoryTooSmall);
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, InsertTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);

  EXPECT_FALSE(tuple_store_->supportsAdHocInsert());
  EXPECT_FALSE(tuple_store_->adHocInsertIsEfficient());

  EXPECT_TRUE(tuple_store_->isCompressed());
  EXPECT_FALSE(tuple_store_->compressedBlockIsBuilt());
  EXPECT_TRUE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(0));
  EXPECT_TRUE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(1));
  EXPECT_TRUE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(2));
  EXPECT_TRUE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(3));
  EXPECT_TRUE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(4));
  EXPECT_TRUE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(5));
  EXPECT_FALSE(tuple_store_->compressedUnbuiltBlockAttributeMayBeCompressed(6));

  // The ad-hoc path should fail to insert.
  std::unique_ptr<Tuple> current_tuple(createSampleTuple(0));
  TupleStorageSubBlock::InsertResult ad_hoc_insert_result = tuple_store_->insertTuple(*current_tuple);
  EXPECT_EQ(-1, ad_hoc_insert_result.inserted_id);
  EXPECT_FALSE(ad_hoc_insert_result.ids_mutated);

  // The block should report itself as empty.
  EXPECT_TRUE(tuple_store_->isEmpty());

  tuple_id current_tid = 0;
  while (computeRequiredStorage(current_tid + 1) < kSubBlockSize) {
    EXPECT_TRUE(tuple_store_->insertTupleInBatch(*current_tuple));
    ++current_tid;
    current_tuple.reset(createSampleTuple(current_tid));
  }

  EXPECT_FALSE(tuple_store_->insertTupleInBatch(*current_tuple));
  EXPECT_FALSE(tuple_store_->isEmpty());

  // Actually build the compressed store and check its metadata afterwards.
  tuple_store_->rebuild();
  EXPECT_FALSE(tuple_store_->isEmpty());
  EXPECT_TRUE(tuple_store_->isPacked());
  EXPECT_EQ(current_tid - 1, tuple_store_->getMaxTupleID());

  EXPECT_TRUE(tuple_store_->isCompressed());
  EXPECT_TRUE(tuple_store_->compressedBlockIsBuilt());

  EXPECT_FALSE(tuple_store_->compressedAttributeIsDictionaryCompressed(0));
  EXPECT_TRUE(tuple_store_->compressedAttributeIsTruncationCompressed(0));
  EXPECT_EQ(1u, tuple_store_->compressedGetCompressedAttributeSize(0));

  EXPECT_TRUE(tuple_store_->compressedAttributeIsDictionaryCompressed(1));
  EXPECT_FALSE(tuple_store_->compressedAttributeIsTruncationCompressed(1));
  EXPECT_EQ(1u, tuple_store_->compressedGetCompressedAttributeSize(1));

  EXPECT_FALSE(tuple_store_->compressedAttributeIsDictionaryCompressed(2));
  EXPECT_TRUE(tuple_store_->compressedAttributeIsTruncationCompressed(2));
  EXPECT_EQ(4u, tuple_store_->compressedGetCompressedAttributeSize(2));

  EXPECT_TRUE(tuple_store_->compressedAttributeIsDictionaryCompressed(3));
  EXPECT_FALSE(tuple_store_->compressedAttributeIsTruncationCompressed(3));
  EXPECT_EQ(2u, tuple_store_->compressedGetCompressedAttributeSize(3));

  EXPECT_TRUE(tuple_store_->compressedAttributeIsDictionaryCompressed(4));
  EXPECT_FALSE(tuple_store_->compressedAttributeIsTruncationCompressed(4));
  EXPECT_EQ(2u, tuple_store_->compressedGetCompressedAttributeSize(4));

  EXPECT_FALSE(tuple_store_->compressedAttributeIsDictionaryCompressed(5));
  EXPECT_FALSE(tuple_store_->compressedAttributeIsTruncationCompressed(5));

  EXPECT_FALSE(tuple_store_->compressedAttributeIsDictionaryCompressed(6));
  EXPECT_FALSE(tuple_store_->compressedAttributeIsTruncationCompressed(6));
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, InsertAfterBuildTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);

  // Insert just a couple of tuples.
  std::unique_ptr<Tuple> current_tuple(createSampleTuple(0));
  EXPECT_TRUE(tuple_store_->insertTupleInBatch(*current_tuple));
  current_tuple.reset(createSampleTuple(1));
  EXPECT_TRUE(tuple_store_->insertTupleInBatch(*current_tuple));

  tuple_store_->rebuild();
  EXPECT_FALSE(tuple_store_->isEmpty());
  EXPECT_TRUE(tuple_store_->isPacked());
  EXPECT_EQ(1, tuple_store_->getMaxTupleID());

  // Even though there is plenty of space, we still expect failure when
  // we attempt to insert in a batch after the block is built.
  current_tuple.reset(createSampleTuple(2));
  EXPECT_FALSE(tuple_store_->insertTupleInBatch(*current_tuple));
  EXPECT_FALSE(tuple_store_->isEmpty());
  EXPECT_TRUE(tuple_store_->isPacked());
  EXPECT_EQ(1, tuple_store_->getMaxTupleID());
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, GetAttributeValueTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);
  fillBlockWithSampleData();

  checkBlockValues();
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, ReloadAndGetAttributeValueTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);
  fillBlockWithSampleData();
  tuple_store_.reset(new CompressedPackedRowStoreTupleStorageSubBlock(*relation_,
                                                                      *tuple_store_description_,
                                                                      false,
                                                                      tuple_store_memory_.get(),
                                                                      kSubBlockSize));

  checkBlockValues();
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockDeathTest, SetAttributeValueTypedTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);

  // Insert just a couple of tuples.
  std::unique_ptr<Tuple> current_tuple(createSampleTuple(0));
  EXPECT_TRUE(tuple_store_->insertTupleInBatch(*current_tuple));
  current_tuple.reset(createSampleTuple(1));
  EXPECT_TRUE(tuple_store_->insertTupleInBatch(*current_tuple));

  tuple_store_->rebuild();
  EXPECT_FALSE(tuple_store_->isEmpty());
  EXPECT_TRUE(tuple_store_->isPacked());
  EXPECT_EQ(1, tuple_store_->getMaxTupleID());

  for (attribute_id attr_id = 0;
       attr_id < relation_->getMaxAttributeId();
       ++attr_id) {
    std::unordered_map<attribute_id, TypedValue> new_values;
    new_values[attr_id] = TypedValue(0);
    EXPECT_FALSE(tuple_store_->canSetAttributeValuesInPlaceTyped(0, new_values));
  }

  // Now attempt to actually set a value in place.
  TypedValue dummy_value(0);
  EXPECT_DEATH(tuple_store_->setAttributeValueInPlaceTyped(0, 0, dummy_value), "");
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, DeleteTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);
  fillBlockWithSampleData();

  tuple_id original_max_tuple_id = tuple_store_->getMaxTupleID();

  // Delete the very last tuple.
  EXPECT_FALSE(tuple_store_->deleteTuple(tuple_store_->getMaxTupleID()));
  EXPECT_EQ(original_max_tuple_id - 1, tuple_store_->getMaxTupleID());

  // Delete the hundredth tuple.
  EXPECT_TRUE(tuple_store_->deleteTuple(100));
  EXPECT_EQ(original_max_tuple_id - 2, tuple_store_->getMaxTupleID());

  // Delete a sequence of tuples.
  TupleIdSequence delete_sequence(tuple_store_->getMaxTupleID() + 1);
  for (tuple_id tid = 199;
       tid <= tuple_store_->getMaxTupleID();
       tid += 100) {
    delete_sequence.set(tid, true);
  }
  EXPECT_TRUE(tuple_store_->bulkDeleteTuples(&delete_sequence));
  EXPECT_EQ(static_cast<tuple_id>(original_max_tuple_id - delete_sequence.numTuples() - 2),
            tuple_store_->getMaxTupleID());

  // Delete a couple of tuples from the very end of the block.
  TupleIdSequence end_delete_sequence(tuple_store_->getMaxTupleID() + 1);
  end_delete_sequence.set(tuple_store_->getMaxTupleID(), true);
  end_delete_sequence.set(tuple_store_->getMaxTupleID() - 1, true);
  EXPECT_FALSE(tuple_store_->bulkDeleteTuples(&end_delete_sequence));
  EXPECT_EQ(static_cast<tuple_id>(
                original_max_tuple_id
                - delete_sequence.numTuples()
                - end_delete_sequence.numTuples()
                - 2),
            tuple_store_->getMaxTupleID());

  // Check that the remaining values are what we expect.
  // Set up some comparators for each attribute.
  PtrVector<UncheckedComparator> eq_comparators;
  for (CatalogRelation::const_iterator attr_it = relation_->begin();
       attr_it != relation_->end();
       ++attr_it) {
    eq_comparators.push_back(ComparisonFactory::GetComparison(ComparisonID::kEqual).makeUncheckedComparatorForTypes(
        attr_it->getType(), attr_it->getType()));
  }

  for (tuple_id tid = 0;
       tid <= tuple_store_->getMaxTupleID();
       ++tid) {
    std::unique_ptr<Tuple> check_tuple(createSampleTuple(tid + (tid - 1) / 99));
    EXPECT_TRUE(tuple_store_->hasTupleWithID(tid));

    for (attribute_id attr_id = 0;
         attr_id <= relation_->getMaxAttributeId();
         ++attr_id) {
      if (GetParam() && check_tuple->getAttributeValue(attr_id).isNull()) {
        EXPECT_EQ(nullptr, tuple_store_->getAttributeValue(tid, attr_id));
        EXPECT_TRUE(tuple_store_->getAttributeValueTyped(tid, attr_id).isNull());
      } else {
        if ((attr_id != 0) && (attr_id != 2)) {
          EXPECT_TRUE(eq_comparators[attr_id].compareDataPtrs(
              check_tuple->getAttributeValue(attr_id).getDataPtr(),
              tuple_store_->getAttributeValue(tid, attr_id)));
        }

        TypedValue attr_value(tuple_store_->getAttributeValueTyped(tid, attr_id));
        EXPECT_TRUE(eq_comparators[attr_id].compareTypedValues(
            check_tuple->getAttributeValue(attr_id),
            attr_value));
      }
    }
  }
}

TEST_P(CompressedPackedRowStoreTupleStorageSubBlockTest, GetMatchesForPredicateTest) {
  initializeTupleStoreDescription();
  initializeNewBlock(kSubBlockSize);
  fillBlockWithSampleData();

  checkPredicateAttr0(ComparisonID::kEqual);
  checkPredicateAttr0(ComparisonID::kNotEqual);
  checkPredicateAttr0(ComparisonID::kLess);
  checkPredicateAttr0(ComparisonID::kLessOrEqual);
  checkPredicateAttr0(ComparisonID::kGreater);
  checkPredicateAttr0(ComparisonID::kGreaterOrEqual);

  checkPredicateAttr1(ComparisonID::kEqual);
  checkPredicateAttr1(ComparisonID::kNotEqual);
  checkPredicateAttr1(ComparisonID::kLess);
  checkPredicateAttr1(ComparisonID::kLessOrEqual);
  checkPredicateAttr1(ComparisonID::kGreater);
  checkPredicateAttr1(ComparisonID::kGreaterOrEqual);

  checkPredicateAttr2(ComparisonID::kEqual);
  checkPredicateAttr2(ComparisonID::kNotEqual);
  checkPredicateAttr2(ComparisonID::kLess);
  checkPredicateAttr2(ComparisonID::kLessOrEqual);
  checkPredicateAttr2(ComparisonID::kGreater);
  checkPredicateAttr2(ComparisonID::kGreaterOrEqual);

  checkPredicateAttr3(ComparisonID::kEqual);
  checkPredicateAttr3(ComparisonID::kNotEqual);
  checkPredicateAttr3(ComparisonID::kLess);
  checkPredicateAttr3(ComparisonID::kLessOrEqual);
  checkPredicateAttr3(ComparisonID::kGreater);
  checkPredicateAttr3(ComparisonID::kGreaterOrEqual);

  checkPredicateAttr4(ComparisonID::kEqual);
  checkPredicateAttr4(ComparisonID::kNotEqual);
  checkPredicateAttr4(ComparisonID::kLess);
  checkPredicateAttr4(ComparisonID::kLessOrEqual);
  checkPredicateAttr4(ComparisonID::kGreater);
  checkPredicateAttr4(ComparisonID::kGreaterOrEqual);

  checkPredicateAttr5(ComparisonID::kEqual);
  checkPredicateAttr5(ComparisonID::kNotEqual);
  checkPredicateAttr5(ComparisonID::kLess);
  checkPredicateAttr5(ComparisonID::kLessOrEqual);
  checkPredicateAttr5(ComparisonID::kGreater);
  checkPredicateAttr5(ComparisonID::kGreaterOrEqual);

  checkPredicateAttr6(ComparisonID::kEqual);
  checkPredicateAttr6(ComparisonID::kNotEqual);
  checkPredicateAttr6(ComparisonID::kLess);
  checkPredicateAttr6(ComparisonID::kLessOrEqual);
  checkPredicateAttr6(ComparisonID::kGreater);
  checkPredicateAttr6(ComparisonID::kGreaterOrEqual);

  // These are used for checking some special predicates below.
  std::unique_ptr<Predicate> predicate;
  std::unique_ptr<TupleIdSequence> matches;

  // Check some predicates which compare an attribute with a literal of a
  // different type.
  // A truncation-compressed attribute:
  predicate.reset(generateNumericComparisonPredicate<DoubleType>(ComparisonID::kEqual, 0, 55.5));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<DoubleType>(ComparisonID::kNotEqual, 0, 55.5));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<DoubleType>(ComparisonID::kGreater, 0, 55.5));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  TupleIdSequence::const_iterator current_match_it = matches->begin();
  for (tuple_id tid = 0;
       tid <= tuple_store_->getMaxTupleID();
       ++tid) {
    if (matchExpected(ComparisonID::kGreater,
                      tid % numeric_limits<int8_t>::max(),
                      55)) {
      ASSERT_NE(current_match_it, matches->end());
      EXPECT_EQ(tid, *current_match_it);
      ++current_match_it;
    } else {
      if (current_match_it != matches->end()) {
        EXPECT_NE(tid, *current_match_it);
      }
    }
  }

  // A dictionary-compressed attribute:
  predicate.reset(generateNumericComparisonPredicate<DoubleType>(ComparisonID::kEqual, 4, -55.5));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<DoubleType>(ComparisonID::kNotEqual, 4, -55.5));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  if (GetParam()) {
    // nulls don't match.
    TupleIdSequence::size_type expected_matches
        = static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1);
    TupleIdSequence::size_type num_nulls
        = (expected_matches / numeric_limits<int16_t>::max())
              * ((numeric_limits<int16_t>::max() / 8) + (numeric_limits<int16_t>::max() % 8 > 4))
          + ((expected_matches % numeric_limits<int16_t>::max()) / 8)
          + (expected_matches % numeric_limits<int16_t>::max() % 8 > 4);
    expected_matches -= num_nulls;
    EXPECT_EQ(expected_matches, matches->numTuples());
  } else {
    EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
              matches->numTuples());
  }

  predicate.reset(generateNumericComparisonPredicate<DoubleType>(ComparisonID::kGreater, 4, -55.5));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  current_match_it = matches->begin();
  for (tuple_id tid = 0;
       tid <= tuple_store_->getMaxTupleID();
       ++tid) {
    if (GetParam() && (tid % numeric_limits<int16_t>::max() % 8 == 4)) {
      if (current_match_it != matches->end()) {
        EXPECT_NE(tid, *current_match_it);
      }
      continue;
    }

    int expected_attr4_value =
        (tid % numeric_limits<int16_t>::max()) & 0x1 ?
        0x1000000 + tid % numeric_limits<int16_t>::max()
        : -(tid % numeric_limits<int16_t>::max());
    if (matchExpected(ComparisonID::kGreater,
                      expected_attr4_value,
                      -56)) {
      ASSERT_NE(current_match_it, matches->end());
      EXPECT_EQ(tid, *current_match_it);
      ++current_match_it;
    } else {
      if (current_match_it != matches->end()) {
        EXPECT_NE(tid, *current_match_it);
      }
    }
  }

  // An uncompressed attribute:
  predicate.reset(generateNumericComparisonPredicate<DoubleType>(
      ComparisonID::kEqual,
      5,
      0.5 + numeric_limits<int32_t>::max() - (tuple_store_->getMaxTupleID() >> 1)));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<DoubleType>(
      ComparisonID::kNotEqual,
      5,
      0.5 + numeric_limits<int32_t>::max() - (tuple_store_->getMaxTupleID() >> 1)));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  if (GetParam()) {
    // nulls don't match.
    TupleIdSequence::size_type expected_matches
        = static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1);
    if (expected_matches % 8 > 6) {
      expected_matches -= expected_matches / 8;
      --expected_matches;
    } else {
      expected_matches -= expected_matches / 8;
    }
    EXPECT_EQ(expected_matches, matches->numTuples());
  } else {
    EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
              matches->numTuples());
  }

  predicate.reset(generateNumericComparisonPredicate<DoubleType>(
      ComparisonID::kGreater,
      5,
      0.5 + numeric_limits<int32_t>::max() - (tuple_store_->getMaxTupleID() >> 1)));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  current_match_it = matches->begin();
  for (tuple_id tid = 0;
       tid <= tuple_store_->getMaxTupleID();
       ++tid) {
    if (GetParam() && (tid % 8 == 6)) {
      if (current_match_it != matches->end()) {
        EXPECT_NE(tid, *current_match_it);
      }
      continue;
    }

    if (matchExpected(ComparisonID::kGreater,
                      numeric_limits<int32_t>::max() - tid,
                      numeric_limits<int32_t>::max() - (tuple_store_->getMaxTupleID() >> 1))) {
      ASSERT_NE(current_match_it, matches->end());
      EXPECT_EQ(tid, *current_match_it);
      ++current_match_it;
    } else {
      if (current_match_it != matches->end()) {
        EXPECT_NE(tid, *current_match_it);
      }
    }
  }

  // Check special fast paths for out-of-range or nonexistent values.
  // A truncated attribute:
  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kEqual, 0, -1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kEqual,
                                                              0,
                                                              numeric_limits<uint8_t>::max() + 1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kNotEqual, 0, -1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kNotEqual,
                                                              0,
                                                              numeric_limits<uint8_t>::max() + 1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kLess, 0, 0));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kLess,
                                                              0,
                                                              numeric_limits<uint8_t>::max() + 1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kLessOrEqual, 0, -1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kLessOrEqual,
                                                              0,
                                                              numeric_limits<uint8_t>::max()));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kGreater, 0, -1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kGreater,
                                                              0,
                                                              numeric_limits<uint8_t>::max()));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kGreaterOrEqual, 0, 0));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1),
            matches->numTuples());

  predicate.reset(generateNumericComparisonPredicate<IntType>(ComparisonID::kGreaterOrEqual,
                                                              0,
                                                              numeric_limits<uint8_t>::max() + 1));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  // A dictionary-coded attribute:
  TupleIdSequence::size_type non_null_values
      = static_cast<TupleIdSequence::size_type>(tuple_store_->getMaxTupleID() + 1);
  if (GetParam()) {
    TupleIdSequence::size_type num_nulls
        = (non_null_values / numeric_limits<int8_t>::max())
              * ((numeric_limits<int8_t>::max() / 8) + (numeric_limits<int8_t>::max() % 8 > 2))
          + ((non_null_values % numeric_limits<int8_t>::max()) / 8)
          + (non_null_values % numeric_limits<int8_t>::max() % 8 > 2);
    non_null_values -= num_nulls;
  }

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kEqual, 1, "5000"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kNotEqual, 1, "5000"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(non_null_values, matches->numTuples());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kLess, 1, "0"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kLess, 1, "a"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(non_null_values, matches->numTuples());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kLessOrEqual, 1, " "));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kLessOrEqual, 1, "99"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(non_null_values, matches->numTuples());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kGreater, 1, " "));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(non_null_values, matches->numTuples());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kGreater, 1, "99"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kGreaterOrEqual, 1, "0"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_EQ(non_null_values, matches->numTuples());

  predicate.reset(generateStringComparisonPredicate(ComparisonID::kGreaterOrEqual, 1, "a"));
  matches.reset(TupleStorePredicateUtil::GetMatchesForPredicateOnTupleStore(*predicate, *tuple_store_));
  EXPECT_TRUE(matches->empty());
}

TEST(CompressedPackedRowStoreTupleStorageSubBlockNullTypeTest, NullTypeTest) {
  // Set up a relation with a single NullType attribute.
  CatalogRelation test_relation(nullptr, "TestRelation");
  CatalogAttribute *nulltype_attr = new CatalogAttribute(&test_relation,
                                                         "nulltype_attr",
                                                         TypeFactory::GetType(kNullType, true));
  ASSERT_EQ(0, test_relation.addAttribute(nulltype_attr));

  // Set up a minimal StorageBlockLayoutDescription.
  StorageBlockLayoutDescription layout_desc;
  layout_desc.set_num_slots(1);
  layout_desc.mutable_tuple_store_description()->set_sub_block_type(
      TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);

  // Check that the description is considered valid.
  EXPECT_TRUE(StorageBlockLayout::DescriptionIsValid(test_relation, layout_desc));

  StorageBlockLayout layout(test_relation, layout_desc);

  // Construct an actual PackedRowStoreTupleStorageSubBlock.
  ScopedBuffer tuple_store_memory(kSlotSizeBytes);
  CompressedPackedRowStoreTupleStorageSubBlock tuple_store(
      test_relation,
      layout_desc.tuple_store_description(),
      true,
      tuple_store_memory.get(),
      kSlotSizeBytes);

  // Insert some NullType values.
  std::vector<TypedValue> attr_values;
  attr_values.emplace_back(kNullType);
  Tuple tuple(std::move(attr_values));

  for (tuple_id tid = 0; tid < 100; ++tid) {
    tuple_store.insertTupleInBatch(tuple);
  }
  tuple_store.rebuild();

  EXPECT_EQ(100, tuple_store.numTuples());

  // Delete some values.
  TupleIdSequence delete_sequence(100);
  delete_sequence.set(5, true);
  delete_sequence.set(25, true);
  delete_sequence.set(45, true);
  delete_sequence.set(65, true);
  delete_sequence.set(85, true);

  EXPECT_TRUE(tuple_store.bulkDeleteTuples(&delete_sequence));
  EXPECT_EQ(95, tuple_store.numTuples());
  ASSERT_EQ(94, tuple_store.getMaxTupleID());

  // Read out values.
  for (tuple_id tid = 0; tid < 95; ++tid) {
    ASSERT_TRUE(tuple_store.hasTupleWithID(tid));
    EXPECT_EQ(nullptr, tuple_store.getAttributeValue(tid, 0));

    TypedValue value = tuple_store.getAttributeValueTyped(tid, 0);
    EXPECT_TRUE(value.isNull());
    EXPECT_EQ(kNullType, value.getTypeID());
  }
}

// Note: INSTANTIATE_TEST_CASE_P has variadic arguments part. If the variable argument part
//       is empty, C++11 standard says it should produce a warning. A warning is converted
//       to an error since we use -Werror as a compiler parameter. It causes Travis to build.
//       This is the reason that we must give an empty string argument as a last parameter
//       to supress warning that clang gives.
INSTANTIATE_TEST_CASE_P(WithAndWithoutNullableAttributes,
                        CompressedPackedRowStoreTupleStorageSubBlockTest,
                        ::testing::Bool(),);  // NOLINT(whitespace/comma)

INSTANTIATE_TEST_CASE_P(WithAndWithoutNullableAttributes,
                        CompressedPackedRowStoreTupleStorageSubBlockDeathTest,
                        ::testing::Bool(),);  // NOLINT(whitespace/comma)

}  // namespace quickstep
