/**
 * 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 <algorithm>
#include <cstddef>
#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "catalog/Catalog.hpp"
#include "catalog/Catalog.pb.h"
#include "catalog/CatalogAttribute.hpp"
#include "catalog/CatalogDatabase.hpp"
#include "catalog/CatalogDatabaseCache.hpp"
#include "catalog/CatalogRelation.hpp"
#include "catalog/CatalogRelationSchema.hpp"
#include "catalog/CatalogTypedefs.hpp"
#include "catalog/IndexScheme.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "storage/SubBlockTypeRegistryMacros.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrVector.hpp"

#include "gtest/gtest.h"

namespace quickstep {

QUICKSTEP_FORCE_SUB_BLOCK_REGISTRATION(BasicColumnStoreTupleStorageSubBlock);
QUICKSTEP_FORCE_SUB_BLOCK_REGISTRATION(CSBTreeIndexSubBlock);
QUICKSTEP_FORCE_SUB_BLOCK_REGISTRATION(CompressedColumnStoreTupleStorageSubBlock);
QUICKSTEP_FORCE_SUB_BLOCK_REGISTRATION(CompressedPackedRowStoreTupleStorageSubBlock);
QUICKSTEP_FORCE_SUB_BLOCK_REGISTRATION(SMAIndexSubBlock);
QUICKSTEP_FORCE_SUB_BLOCK_REGISTRATION(SplitRowStoreTupleStorageSubBlock);

class CatalogTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    db_ = cat_.getDatabaseByIdMutable(cat_.addDatabase(new CatalogDatabase(nullptr, "db")));
  }

  CatalogRelation* createCatalogRelation(const std::string &name, bool temporary = false) {
    return db_->getRelationByIdMutable(db_->addRelation(new CatalogRelation(nullptr, name, -1, temporary)));
  }

  static void CompareCatalogAttribute(const CatalogAttribute &expected, const CatalogAttribute &checked) {
    EXPECT_EQ(expected.getID(), checked.getID());
    EXPECT_EQ(expected.getName(), checked.getName());
    EXPECT_TRUE(expected.getType().equals(checked.getType()));
    EXPECT_EQ(expected.getDisplayName(), checked.getDisplayName());
  }

  static void CompareTupleStorageSubBlockDescription(
      const TupleStorageSubBlockDescription &expected,
      const TupleStorageSubBlockDescription &checked) {
    EXPECT_EQ(expected.sub_block_type(), checked.sub_block_type());

    switch (expected.sub_block_type()) {
      case TupleStorageSubBlockDescription::BASIC_COLUMN_STORE:
        EXPECT_TRUE(expected.HasExtension(BasicColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
        EXPECT_TRUE(checked.HasExtension(BasicColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
        EXPECT_EQ(
            expected.GetExtension(BasicColumnStoreTupleStorageSubBlockDescription::sort_attribute_id),
            checked.GetExtension(BasicColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
        break;
      case TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE:
        ASSERT_EQ(
            expected.ExtensionSize(CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id),
            checked.ExtensionSize(CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id));

        for (int i = 0;
             i < expected.ExtensionSize(
                     CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id);
             ++i) {
          EXPECT_EQ(
              expected.GetExtension(
                  CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, i),
              checked.GetExtension(
                  CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, i));
        }
        break;
      case TupleStorageSubBlockDescription::COMPRESSED_COLUMN_STORE:
        EXPECT_TRUE(expected.HasExtension(CompressedColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
        EXPECT_TRUE(checked.HasExtension(CompressedColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));
        EXPECT_EQ(
            expected.GetExtension(CompressedColumnStoreTupleStorageSubBlockDescription::sort_attribute_id),
            checked.GetExtension(CompressedColumnStoreTupleStorageSubBlockDescription::sort_attribute_id));

        ASSERT_EQ(
            expected.ExtensionSize(CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id),
            checked.ExtensionSize(CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id));

        for (int i = 0;
             i < expected.ExtensionSize(CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id);
             ++i) {
          EXPECT_EQ(
              expected.GetExtension(CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id, i),
              checked.GetExtension(CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id, i));
        }
        break;
      case TupleStorageSubBlockDescription::SPLIT_ROW_STORE:
        break;
      default:
        FATAL_ERROR("Unknown TupleStorageSubBlockType encountered in CompareTupleStorageSubBlockDescription");
    }
  }

  static void CompareIndexSubBlockDescription(
      const IndexSubBlockDescription &expected,
      const IndexSubBlockDescription &checked) {
    EXPECT_EQ(expected.sub_block_type(), checked.sub_block_type());

    ASSERT_EQ(expected.indexed_attribute_ids_size(), checked.indexed_attribute_ids_size());
    for (int i = 0; i < expected.indexed_attribute_ids_size(); ++i) {
      EXPECT_EQ(expected.indexed_attribute_ids(i), checked.indexed_attribute_ids(i));
    }
  }

  static void CompareStorageBlockLayoutDescription(
      const StorageBlockLayoutDescription &expected,
      const StorageBlockLayoutDescription &checked) {
    EXPECT_EQ(expected.num_slots(), checked.num_slots());
    CompareTupleStorageSubBlockDescription(expected.tuple_store_description(), checked.tuple_store_description());

    ASSERT_EQ(expected.index_description_size(), checked.index_description_size());
    for (int i = 0; i < expected.index_description_size(); ++i) {
      CompareIndexSubBlockDescription(expected.index_description(i), checked.index_description(i));
    }
  }

  static void CompareCatalogRelation(const CatalogRelation &expected, const CatalogRelation &checked) {
    EXPECT_EQ(expected.getID(), checked.getID());
    EXPECT_EQ(expected.getName(), checked.getName());
    EXPECT_EQ(expected.isTemporary(), checked.isTemporary());

    CompareStorageBlockLayoutDescription(
        expected.getDefaultStorageBlockLayout().getDescription(),
        checked.getDefaultStorageBlockLayout().getDescription());

    EXPECT_EQ(expected.blocks_, checked.blocks_);

    ASSERT_EQ(expected.size(), checked.size());
    for (CatalogRelation::const_iterator it1 = expected.begin(), it2 = checked.begin();
         it1 != expected.end();
         ++it1, ++it2) {
      CompareCatalogAttribute(*it1, *it2);
    }

    ASSERT_EQ((expected.index_scheme_ != nullptr), (checked.index_scheme_ != nullptr));

    if (checked.index_scheme_ != nullptr) {
      ASSERT_EQ(expected.index_scheme_->getNumIndices(), checked.index_scheme_->getNumIndices());

      std::string expected_index_scheme_serialized_proto, checked_index_scheme_serialized_proto;
      expected.index_scheme_->getProto().SerializeToString(&expected_index_scheme_serialized_proto);
      checked.index_scheme_->getProto().SerializeToString(&checked_index_scheme_serialized_proto);
      std::sort(expected_index_scheme_serialized_proto.begin(), expected_index_scheme_serialized_proto.end());
      std::sort(checked_index_scheme_serialized_proto.begin(), checked_index_scheme_serialized_proto.end());
      EXPECT_EQ(expected_index_scheme_serialized_proto, checked_index_scheme_serialized_proto);
    }
  }

  static void CompareCatalogDatabase(const CatalogDatabase &expected, const CatalogDatabase &checked) {
    EXPECT_EQ(expected.getID(), checked.getID());
    EXPECT_EQ(expected.getName(), checked.getName());
    ASSERT_EQ(expected.size(), checked.size());
    for (CatalogDatabase::const_iterator it1 = expected.begin(), it2 = checked.begin();
         it1 != expected.end();
         ++it1, ++it2) {
      CompareCatalogRelation(*it1, *it2);
    }
  }

  void compareCatalogDatabaseCache(const CatalogDatabaseCache &cache) {
    ASSERT_EQ(db_->size(), cache.size());
    for (const CatalogRelationSchema &expected : *db_) {
      const relation_id rel_id = expected.getID();

      ASSERT_TRUE(cache.hasRelationWithId(rel_id));
      const CatalogRelationSchema &checked = cache.getRelationSchemaById(rel_id);

      EXPECT_EQ(rel_id, checked.getID());
      EXPECT_EQ(expected.getName(), checked.getName());
      EXPECT_EQ(expected.isTemporary(), checked.isTemporary());

      ASSERT_EQ(expected.size(), checked.size());
      for (auto cit_expected = expected.begin(), cit_checked = checked.begin();
           cit_expected != expected.end();
           ++cit_expected, ++cit_checked) {
        CompareCatalogAttribute(*cit_expected, *cit_checked);
      }
      const std::vector<std::size_t>& expected_max_lengths =
          expected.getMaximumAttributeByteLengths();
      const std::vector<std::size_t>& checked_max_lengths =
          checked.getMaximumAttributeByteLengths();
      ASSERT_EQ(expected_max_lengths.size(), checked_max_lengths.size());
      for (attribute_id len_index = 0;
           static_cast<std::size_t>(len_index) < expected_max_lengths.size();
           ++len_index) {
        EXPECT_EQ(expected_max_lengths[len_index],
                  checked_max_lengths[len_index]);
      }
    }
  }

  void checkCatalogSerialization() {
    Catalog cat_from_proto(cat_.getProto());
    ASSERT_EQ(cat_.size(), cat_from_proto.size());
    for (Catalog::const_iterator it = cat_.begin(), it_from_proto = cat_from_proto.begin();
         it != cat_.end();
         ++it, ++it_from_proto) {
      CompareCatalogDatabase(*it, *it_from_proto);
    }
  }

  Catalog cat_;
  // db_ is owned by cat_.
  CatalogDatabase *db_;
};

TEST_F(CatalogTest, CatalogAttributeSerializationTest) {
  CatalogRelation* const rel_numeric = createCatalogRelation("rel_numeric");

  rel_numeric->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 14));
  rel_numeric->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 7));

  rel_numeric->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt), -1 /* id */, "int"));
  rel_numeric->addAttribute(
      new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong), -1 /* id */, "long"));
  rel_numeric->addAttribute(
      new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat), -1 /* id */, "float"));
  rel_numeric->addAttribute(
      new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble), -1 /* id */, "double"));

  CatalogRelation* const rel_string = createCatalogRelation("rel_string");

  rel_string->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 19));
  rel_string->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 4));

  StorageBlockLayoutDescription layout_description_string(
      rel_string->getDefaultStorageBlockLayout().getDescription());

  std::size_t str_type_length = 0;
  rel_string->addAttribute(
      new CatalogAttribute(nullptr,
                           "char_length_0",
                           TypeFactory::GetType(kChar, str_type_length),
                           -1 /* id */,
                           "char_0"));
  rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_0", TypeFactory::GetType(kVarChar, str_type_length)));

  str_type_length = 8;
  rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_8", TypeFactory::GetType(kChar, str_type_length)));
  rel_string->addAttribute(
      new CatalogAttribute(nullptr,
                           "var_char_length_8",
                           TypeFactory::GetType(kVarChar, str_type_length),
                           -1 /* id */,
                           "vchar_8"));

  str_type_length = 1024;
  rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_1024", TypeFactory::GetType(kChar, str_type_length)));
  rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_1024", TypeFactory::GetType(kVarChar, str_type_length)));

  str_type_length = 65536;
  rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_65536", TypeFactory::GetType(kChar, str_type_length)));
  rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_65536", TypeFactory::GetType(kVarChar, str_type_length)));

  // COMPRESSED_PACKED_ROW_STORE supports variable-length attributes.
  TupleStorageSubBlockDescription* tuple_store_description_string =
      layout_description_string.mutable_tuple_store_description();
  tuple_store_description_string->set_sub_block_type(
      TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  for (int i = 0; i <= rel_string->getMaxAttributeId(); ++i) {
    tuple_store_description_string->AddExtension(
        CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, i);
  }
  rel_string->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel_string, layout_description_string));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, NullableCatalogAttributeSerializationTest) {
  CatalogRelation* const rel = createCatalogRelation("rel");

  StorageBlockLayoutDescription layout_description(
      rel->getDefaultStorageBlockLayout().getDescription());

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_int_nullable", TypeFactory::GetType(kInt, true)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_long_nullable", TypeFactory::GetType(kLong, true)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_float_nullable", TypeFactory::GetType(kFloat, true)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_double_nullable", TypeFactory::GetType(kDouble, true)));

  std::size_t str_type_length = 0;
  rel->addAttribute(
      new CatalogAttribute(nullptr, "char_length_0_nullable", TypeFactory::GetType(kChar, str_type_length, true)));
  rel->addAttribute(
      new CatalogAttribute(nullptr,
                           "var_char_length_0_nullable",
                           TypeFactory::GetType(kVarChar, str_type_length, true)));

  str_type_length = 8;
  rel->addAttribute(
      new CatalogAttribute(nullptr, "char_length_8_nullable", TypeFactory::GetType(kChar, str_type_length, true)));
  rel->addAttribute(
      new CatalogAttribute(nullptr,
                           "var_char_length_8_nullable",
                           TypeFactory::GetType(kVarChar, str_type_length, true)));

  str_type_length = 1024;
  rel->addAttribute(
      new CatalogAttribute(nullptr, "char_length_1024_nullable", TypeFactory::GetType(kChar, str_type_length, true)));
  rel->addAttribute(
      new CatalogAttribute(nullptr,
                           "var_char_length_1024_nullable",
                           TypeFactory::GetType(kVarChar, str_type_length, true)));

  str_type_length = 65536;
  rel->addAttribute(
      new CatalogAttribute(nullptr, "char_length_65536_nullable", TypeFactory::GetType(kChar, str_type_length, true)));
  rel->addAttribute(
      new CatalogAttribute(nullptr,
                           "var_char_length_65536_nullable",
                           TypeFactory::GetType(kVarChar, str_type_length, true)));

  TupleStorageSubBlockDescription* tuple_store_description =
      layout_description.mutable_tuple_store_description();
  tuple_store_description->set_sub_block_type(
      TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  for (int i = 0; i <= rel->getMaxAttributeId(); ++i) {
    tuple_store_description->AddExtension(
        CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, i);
  }
  rel->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel, layout_description));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, TemporaryCatalogRelationSerializationTest) {
  CatalogRelation* const tmp_rel_numeric = createCatalogRelation("tmp_rel_numeric", true);

  tmp_rel_numeric->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 14));
  tmp_rel_numeric->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 7));

  tmp_rel_numeric->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt)));
  tmp_rel_numeric->addAttribute(new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong)));
  tmp_rel_numeric->addAttribute(new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat)));
  tmp_rel_numeric->addAttribute(new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble)));

  CatalogRelation* const tmp_rel_string = createCatalogRelation("tmp_rel_string", true);

  tmp_rel_string->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 19));
  tmp_rel_string->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 4));

  StorageBlockLayoutDescription layout_description_string(
      tmp_rel_string->getDefaultStorageBlockLayout().getDescription());

  std::size_t str_type_length = 0;
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_0", TypeFactory::GetType(kChar, str_type_length)));
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_0", TypeFactory::GetType(kVarChar, str_type_length)));

  str_type_length = 8;
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_8", TypeFactory::GetType(kChar, str_type_length)));
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_8", TypeFactory::GetType(kVarChar, str_type_length)));

  str_type_length = 1024;
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_1024", TypeFactory::GetType(kChar, str_type_length)));
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_1024", TypeFactory::GetType(kVarChar, str_type_length)));

  str_type_length = 65536;
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "char_length_65536", TypeFactory::GetType(kChar, str_type_length)));
  tmp_rel_string->addAttribute(
      new CatalogAttribute(nullptr, "var_char_length_65536", TypeFactory::GetType(kVarChar, str_type_length)));

  // COMPRESSED_PACKED_ROW_STORE supports variable-length attributes.
  TupleStorageSubBlockDescription* tuple_store_description_string =
      layout_description_string.mutable_tuple_store_description();
  tuple_store_description_string->set_sub_block_type(
      TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  for (int i = 0; i <= tmp_rel_string->getMaxAttributeId(); ++i) {
    tuple_store_description_string->AddExtension(
        CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, i);
  }
  tmp_rel_string->setDefaultStorageBlockLayout(new StorageBlockLayout(*tmp_rel_string, layout_description_string));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, DroppedCatalogRelationSerializationTest) {
  for (int i = 0; i < 20; ++i) {
    std::ostringstream oss;
    oss << "rel" << i;
    createCatalogRelation(oss.str());
  }

  db_->dropRelationByName("rel10");

  checkCatalogSerialization();
}

TEST_F(CatalogTest, CatalogBasicColumnStoreSerializationTest) {
  CatalogRelation* const rel = createCatalogRelation("rel");
  StorageBlockLayoutDescription layout_description(rel->getDefaultStorageBlockLayout().getDescription());

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble)));

  const std::size_t str_type_length = 120;
  const attribute_id attr_id =
      rel->addAttribute(new CatalogAttribute(nullptr, "attr_char", TypeFactory::GetType(kChar, str_type_length)));
  // NOTE(zuyu): BasicColumnStoreTupleStorageSubBlock does NOT support variable-length attributes.

  TupleStorageSubBlockDescription* tuple_store_description =
      layout_description.mutable_tuple_store_description();
  tuple_store_description->set_sub_block_type(TupleStorageSubBlockDescription::BASIC_COLUMN_STORE);
  tuple_store_description->SetExtension(
      BasicColumnStoreTupleStorageSubBlockDescription::sort_attribute_id, attr_id);

  rel->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel, layout_description));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, CatalogCompressedPackedRowStoreSerializationTest) {
  CatalogRelation* const rel = createCatalogRelation("rel");
  StorageBlockLayoutDescription layout_description(rel->getDefaultStorageBlockLayout().getDescription());

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble)));

  const std::size_t str_type_length = 1024;
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_char", TypeFactory::GetType(kChar, str_type_length)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_var_char", TypeFactory::GetType(kVarChar, str_type_length)));

  TupleStorageSubBlockDescription* tuple_store_description =
      layout_description.mutable_tuple_store_description();
  tuple_store_description->set_sub_block_type(
      TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE);
  for (int i = 0; i <= rel->getMaxAttributeId(); ++i) {
    tuple_store_description->AddExtension(
        CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, i);
  }

  rel->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel, layout_description));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, CatalogCompressedColumnStoreSerializationTest) {
  CatalogRelation* const rel = createCatalogRelation("rel");
  StorageBlockLayoutDescription layout_description(rel->getDefaultStorageBlockLayout().getDescription());

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble)));

  const std::size_t str_type_length = 65536;
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_char", TypeFactory::GetType(kChar, str_type_length)));
  const attribute_id attr_id =
      rel->addAttribute(
          new CatalogAttribute(nullptr, "attr_var_char", TypeFactory::GetType(kVarChar, str_type_length)));

  TupleStorageSubBlockDescription* tuple_store_description =
      layout_description.mutable_tuple_store_description();
  tuple_store_description->set_sub_block_type(
      TupleStorageSubBlockDescription::COMPRESSED_COLUMN_STORE);
  tuple_store_description->SetExtension(
      CompressedColumnStoreTupleStorageSubBlockDescription::sort_attribute_id, attr_id);
  for (int i = 0; i <= rel->getMaxAttributeId(); ++i) {
    tuple_store_description->AddExtension(
        CompressedColumnStoreTupleStorageSubBlockDescription::compressed_attribute_id, i);
  }

  rel->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel, layout_description));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, CatalogSplitRowStoreSerializationTest) {
  CatalogRelation* const rel = createCatalogRelation("rel");
  StorageBlockLayoutDescription layout_description(rel->getDefaultStorageBlockLayout().getDescription());

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble)));

  const std::size_t str_type_length = std::numeric_limits<std::size_t>::max();
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_char", TypeFactory::GetType(kChar, str_type_length)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_var_char", TypeFactory::GetType(kVarChar, str_type_length)));

  layout_description.mutable_tuple_store_description()->set_sub_block_type(
      TupleStorageSubBlockDescription::SPLIT_ROW_STORE);

  rel->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel, layout_description));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, CatalogIndexTest) {
  CatalogRelation* const rel = createCatalogRelation("rel");
  StorageBlockLayoutDescription layout_description(rel->getDefaultStorageBlockLayout().getDescription());

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_idx1", TypeFactory::GetType(kInt)));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_idx2", TypeFactory::GetType(kInt)));

  layout_description.mutable_tuple_store_description()->set_sub_block_type(
      TupleStorageSubBlockDescription::SPLIT_ROW_STORE);

  rel->setDefaultStorageBlockLayout(new StorageBlockLayout(*rel, layout_description));

  IndexSubBlockDescription index_description;
  index_description.set_sub_block_type(IndexSubBlockDescription::CSB_TREE);
  index_description.add_indexed_attribute_ids(rel->getAttributeByName("attr_idx1")->getID());

  EXPECT_TRUE(rel->addIndex("idx1", std::move(index_description)));
  EXPECT_TRUE(rel->hasIndexWithName("idx1"));
  // Adding an index with duplicate name should return false.
  EXPECT_FALSE(rel->addIndex("idx1", std::move(index_description)));
  // Adding an index of same type with different name on the same attribute should return false.
  EXPECT_FALSE(rel->addIndex("idx2", std::move(index_description)));

  index_description.Clear();
  index_description.set_sub_block_type(IndexSubBlockDescription::CSB_TREE);
  index_description.add_indexed_attribute_ids(rel->getAttributeByName("attr_idx2")->getID());

  EXPECT_TRUE(rel->addIndex("idx2", std::move(index_description)));
  EXPECT_TRUE(rel->hasIndexWithName("idx2"));

  checkCatalogSerialization();
}

TEST_F(CatalogTest, CatalogDatabaseCacheTest) {
  CatalogRelation * const rel = createCatalogRelation("rel");

  rel->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 7));
  rel->addBlock(BlockIdUtil::GetBlockId(0 /* domain */, 14));

  rel->addAttribute(new CatalogAttribute(nullptr, "attr_int", TypeFactory::GetType(kInt), -1 /* id */, "int"));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_long", TypeFactory::GetType(kLong)));
  rel->addAttribute(
      new CatalogAttribute(nullptr, "attr_float", TypeFactory::GetType(kFloat), -1 /* id */, "float"));
  rel->addAttribute(new CatalogAttribute(nullptr, "attr_double", TypeFactory::GetType(kDouble)));

  CatalogDatabaseCache cache(db_->getProto());
  compareCatalogDatabaseCache(cache);

  // Test dropping relations in the cache.
  cache.dropRelationById(rel->getID());
  ASSERT_EQ(0u, cache.size());

  // CatalogRelactionSchema changes.
  const std::size_t str_type_length = 8;
  rel->addAttribute(
      new CatalogAttribute(nullptr, "char_length_8", TypeFactory::GetType(kChar, str_type_length)));
  rel->addAttribute(
      new CatalogAttribute(nullptr,
                           "var_char_length_8",
                           TypeFactory::GetType(kVarChar, str_type_length),
                           -1 /* id */,
                           "vchar_8"));

  // Update the cache after the schema changed.
  cache.update(db_->getProto());
  compareCatalogDatabaseCache(cache);
}

}  // namespace quickstep
