/**
 * 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 <cstdlib>
#include <cstring>
#include <utility>
#include <vector>

#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypedValue.hpp"
#include "types/TypeID.hpp"
#include "types/containers/ColumnVector.hpp"

#include "gtest/gtest.h"

namespace quickstep {

TEST(ColumnVectorTest, NativeUsableForTypeTest) {
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kInt, false)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kInt, true)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kLong, false)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kLong, true)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kFloat, false)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kFloat, true)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kDouble, false)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kDouble, true)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kChar, 20, false)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kChar, 20, true)));
  EXPECT_FALSE(NativeColumnVector::UsableForType(TypeFactory::GetType(kVarChar, 20, false)));
  EXPECT_FALSE(NativeColumnVector::UsableForType(TypeFactory::GetType(kVarChar, 20, true)));
  EXPECT_TRUE(NativeColumnVector::UsableForType(TypeFactory::GetType(kNullType, true)));
}

TEST(ColumnVectorTest, NativeIntTest) {
  // Randomly shuffle a sequence of ints.
  std::vector<int> values;
  for (int i = -50; i < 50; ++i) {
    values.push_back(i);
  }
  std::random_shuffle(values.begin(), values.end());

  NativeColumnVector column_vector(TypeFactory::GetType(kInt, false), values.size());
  EXPECT_TRUE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  // Append values one-by-one, alternating between typed and untyped.
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i & 0x1) {
      column_vector.appendUntypedValue(&(values[i]));
    } else {
      column_vector.appendTypedValue(TypedValue(values[i]));
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < values.size(); ++i) {
    EXPECT_EQ(values[i], *static_cast<const int*>(column_vector.getUntypedValue(i)));
    EXPECT_EQ(values[i], column_vector.getTypedValue(i).getLiteral<int>());
  }

  // Also try inserting in random order using positional writes.
  NativeColumnVector column_vector_positional(TypeFactory::GetType(kInt, false),
                                              values.size());
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(values.size(), column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < values.size(); ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    if (pos & 0x1) {
      column_vector_positional.positionalWriteUntypedValue(pos, &(values[pos]));
    } else {
      column_vector_positional.positionalWriteTypedValue(pos, TypedValue(values[pos]));
    }
  }

  EXPECT_EQ(values.size(), column_vector_positional.size());
  for (std::size_t i = 0; i < values.size(); ++i) {
    EXPECT_EQ(values[i], *static_cast<const int*>(column_vector_positional.getUntypedValue(i)));
    EXPECT_EQ(values[i], column_vector_positional.getTypedValue(i).getLiteral<int>());
  }

  // Reshuffle and overwrite values in-place in the same ColumnVector.
  std::random_shuffle(values.begin(), values.end());
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    if (pos & 0x1) {
      column_vector_positional.positionalWriteUntypedValue(pos, &(values[pos]));
    } else {
      column_vector_positional.positionalWriteTypedValue(pos, TypedValue(values[pos]));
    }
  }

  EXPECT_EQ(values.size(), column_vector_positional.size());
  for (std::size_t i = 0; i < values.size(); ++i) {
    EXPECT_EQ(values[i], *static_cast<const int*>(column_vector_positional.getUntypedValue(i)));
    EXPECT_EQ(values[i], column_vector_positional.getTypedValue(i).getLiteral<int>());
  }
}

TEST(ColumnVectorTest, NativeNullableIntTest) {
  // Randomly shuffle a sequence of ints.
  std::vector<int> values;
  for (int i = -50; i < 50; ++i) {
    values.push_back(i);
  }
  std::random_shuffle(values.begin(), values.end());

  NativeColumnVector column_vector(TypeFactory::GetType(kInt, true), values.size());
  EXPECT_TRUE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  // Append values one-by-one, alternating between typed and untyped.
  for (std::size_t i = 0; i < values.size(); ++i) {
    // Use a NULL in place of every 5th value.
    if (i % 5 == 0) {
      if (i & 0x1) {
        column_vector.appendNullValue();
      } else {
        column_vector.appendTypedValue(TypedValue(kInt));
      }
    } else {
      if (i & 0x1) {
        column_vector.appendUntypedValue(&(values[i]));
      } else {
        column_vector.appendTypedValue(TypedValue(values[i]));
      }
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
      EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
    } else {
      EXPECT_EQ(values[i], *static_cast<const int*>(column_vector.getUntypedValue(i)));
      EXPECT_EQ(values[i], column_vector.getTypedValue(i).getLiteral<int>());
    }
  }

  // Also try inserting in random order using positional writes.
  NativeColumnVector column_vector_positional(TypeFactory::GetType(kInt, true),
                                              values.size());
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(values.size(), column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < values.size(); ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      if (pos & 0x1) {
        column_vector_positional.positionalWriteNullValue(pos);
      } else {
        column_vector_positional.positionalWriteTypedValue(pos, TypedValue(kInt));
      }
    } else {
      if (pos & 0x1) {
        column_vector_positional.positionalWriteUntypedValue(pos, &(values[pos]));
      } else {
        column_vector_positional.positionalWriteTypedValue(pos, TypedValue(values[pos]));
      }
    }
  }

  EXPECT_EQ(values.size(), column_vector_positional.size());
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_EQ(values[i], *static_cast<const int*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(values[i], column_vector_positional.getTypedValue(i).getLiteral<int>());
    }
  }

  // Reshuffle and overwrite values in-place in the same ColumnVector.
  std::random_shuffle(values.begin(), values.end());
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      if (pos & 0x1) {
        column_vector_positional.positionalWriteNullValue(pos);
      } else {
        column_vector_positional.positionalWriteTypedValue(pos, TypedValue(kInt));
      }
    } else {
      if (pos & 0x1) {
        column_vector_positional.positionalWriteUntypedValue(pos, &(values[pos]));
      } else {
        column_vector_positional.positionalWriteTypedValue(pos, TypedValue(values[pos]));
      }
    }
  }

  EXPECT_EQ(values.size(), column_vector_positional.size());
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_EQ(values[i], *static_cast<const int*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(values[i], column_vector_positional.getTypedValue(i).getLiteral<int>());
    }
  }
}

TEST(ColumnVectorTest, IndirectIntTest) {
  // Randomly shuffle a sequence of ints.
  std::vector<int> values;
  for (int i = -50; i < 50; ++i) {
    values.push_back(i);
  }
  std::random_shuffle(values.begin(), values.end());

  // Make an IndirectColumnVector for nullable ints.
  IndirectColumnVector column_vector(TypeFactory::GetType(kInt, true), values.size());
  EXPECT_FALSE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  for (std::size_t i = 0; i < values.size(); ++i) {
    TypedValue value(values[i]);
    // Use a NULL in place of every 5th value.
    if (i % 5 == 0) {
      value = TypedValue(kInt);
    }

    // Alternate between copy and move.
    if (i & 0x1) {
      column_vector.appendTypedValue(value);
    } else {
      column_vector.appendTypedValue(std::move(value));
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
      EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
    } else {
      EXPECT_EQ(values[i], *static_cast<const int*>(column_vector.getUntypedValue(i)));
      EXPECT_EQ(values[i], column_vector.getTypedValue(i).getLiteral<int>());
    }
  }

  // Also try inserting in random order using positional writes.
  IndirectColumnVector column_vector_positional(TypeFactory::GetType(kInt, true),
                                              values.size());
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(values.size(), column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < values.size(); ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    TypedValue value(values[pos]);
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      value = TypedValue(kInt);
    }

    // Alternate between copy and move.
    if (pos & 0x1) {
      column_vector_positional.positionalWriteTypedValue(pos, value);
    } else {
      column_vector_positional.positionalWriteTypedValue(pos, std::move(value));
    }
  }

  EXPECT_EQ(values.size(), column_vector_positional.size());
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_EQ(values[i], *static_cast<const int*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(values[i], column_vector_positional.getTypedValue(i).getLiteral<int>());
    }
  }

  // Reshuffle and overwrite values in-place in the same ColumnVector.
  std::random_shuffle(values.begin(), values.end());
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    TypedValue value(values[pos]);
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      value = TypedValue(kInt);
    }

    // Alternate between copy and move.
    if (pos & 0x1) {
      column_vector_positional.positionalWriteTypedValue(pos, value);
    } else {
      column_vector_positional.positionalWriteTypedValue(pos, std::move(value));
    }
  }

  EXPECT_EQ(values.size(), column_vector_positional.size());
  for (std::size_t i = 0; i < values.size(); ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_EQ(values[i], *static_cast<const int*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(values[i], column_vector_positional.getTypedValue(i).getLiteral<int>());
    }
  }
}


const char *kSampleStrings[] = {
  "Twilight Sparkle",
  "Rarity",
  "Pinkie Pie",
  "Applejack",
  "Rainbow Dash",
  "Fluttershy",
  "Celestia",
  "Luna",
  "Cadence",
  "Applebloom",
  "Scootaloo",
  "Sweetie Belle",
  "Zecora",
  "Big Macintosh",
  "Granny Smith",
  "Shining Armor",
  "Cheerilee",
  "Diamond Tiara",
  "Silver Spoon",
  "Photo Finish",
  "DJ Pon-3",
  "Snips",
  "Snails",
  "Derpy Hooves"
};

TEST(ColumnVectorTest, NativeCharTest) {
  // Make a contiguous array to store all strings.
  const std::size_t num_sample_strings = sizeof(kSampleStrings) / sizeof(kSampleStrings[0]);

  char *contiguous_strings = static_cast<char*>(std::malloc(20 * num_sample_strings));
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    std::strcpy(contiguous_strings + 20 * i, kSampleStrings[i]);  // NOLINT(runtime/printf)
  }

  NativeColumnVector column_vector(TypeFactory::GetType(kChar, 20, false), num_sample_strings);
  EXPECT_TRUE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  // Append values one-by-one, alternating between typed and untyped.
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i & 0x1) {
      column_vector.appendUntypedValue(contiguous_strings + 20 * i);
    } else {
      if (i & 0x2) {
        column_vector.appendTypedValue(TypedValue(kChar, contiguous_strings + 20 * i, 20));
      } else {
        column_vector.appendTypedValue(TypedValue(kChar,
                                                  kSampleStrings[i],
                                                  std::strlen(kSampleStrings[i]) + 1));
      }
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    EXPECT_STREQ(kSampleStrings[i], static_cast<const char*>(column_vector.getUntypedValue(i)));
    EXPECT_EQ(std::strlen(kSampleStrings[i]),
              column_vector.getTypedValue(i).getAsciiStringLength());
    EXPECT_STREQ(kSampleStrings[i],
                 static_cast<const char*>(column_vector.getTypedValue(i).getDataPtr()));
  }

  // Also try inserting in random order using positional writes.
  NativeColumnVector column_vector_positional(TypeFactory::GetType(kChar, 20, false),
                                              num_sample_strings);
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(num_sample_strings, column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    if (pos & 0x1) {
      column_vector_positional.positionalWriteUntypedValue(
          pos,
          contiguous_strings + 20 * pos);
    } else {
      if (pos & 0x2) {
        column_vector_positional.positionalWriteTypedValue(
            pos,
            TypedValue(kChar, contiguous_strings + 20 * pos, 20));
      } else {
        column_vector_positional.positionalWriteTypedValue(
            pos,
            TypedValue(kChar,
                       kSampleStrings[pos],
                       std::strlen(kSampleStrings[pos]) + 1));
      }
    }
  }

  EXPECT_EQ(num_sample_strings, column_vector_positional.size());
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    EXPECT_STREQ(kSampleStrings[i],
                 static_cast<const char*>(column_vector_positional.getUntypedValue(i)));
    EXPECT_EQ(std::strlen(kSampleStrings[i]),
              column_vector_positional.getTypedValue(i).getAsciiStringLength());
    EXPECT_STREQ(kSampleStrings[i],
                 static_cast<const char*>(column_vector_positional.getTypedValue(i).getDataPtr()));
  }

  std::free(contiguous_strings);
}

TEST(ColumnVectorTest, NativeNullableCharTest) {
  // Make a contiguous array to store all strings.
  const std::size_t num_sample_strings = sizeof(kSampleStrings) / sizeof(kSampleStrings[0]);

  char *contiguous_strings = static_cast<char*>(std::malloc(20 * num_sample_strings));
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    std::strcpy(contiguous_strings + 20 * i, kSampleStrings[i]);  // NOLINT(runtime/printf)
  }

  NativeColumnVector column_vector(TypeFactory::GetType(kChar, 20, true), num_sample_strings);
  EXPECT_TRUE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  // Append values one-by-one, alternating between typed and untyped.
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    // Use a NULL in place of every 5th value.
    if (i % 5 == 0) {
      if (i & 0x1) {
        column_vector.appendNullValue();
      } else {
        column_vector.appendTypedValue(TypedValue(kChar));
      }
    } else {
      if (i & 0x1) {
        column_vector.appendUntypedValue(contiguous_strings + 20 * i);
      } else {
        if (i & 0x2) {
          column_vector.appendTypedValue(TypedValue(kChar, contiguous_strings + 20 * i, 20));
        } else {
          column_vector.appendTypedValue(TypedValue(kChar,
                                                    kSampleStrings[i],
                                                    std::strlen(kSampleStrings[i]) + 1));
        }
      }
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
      EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
    } else {
      EXPECT_STREQ(kSampleStrings[i], static_cast<const char*>(column_vector.getUntypedValue(i)));
      EXPECT_EQ(std::strlen(kSampleStrings[i]),
                column_vector.getTypedValue(i).getAsciiStringLength());
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector.getTypedValue(i).getDataPtr()));
    }
  }

  // Also try inserting in random order using positional writes.
  NativeColumnVector column_vector_positional(TypeFactory::GetType(kChar, 20, true),
                                              num_sample_strings);
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(num_sample_strings, column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      if (pos & 0x1) {
        column_vector_positional.positionalWriteNullValue(pos);
      } else {
        column_vector_positional.positionalWriteTypedValue(pos, TypedValue(kChar));
      }
    } else {
      if (pos & 0x1) {
        column_vector_positional.positionalWriteUntypedValue(pos, contiguous_strings + 20 * pos);
      } else {
        if (pos & 0x2) {
          column_vector_positional.positionalWriteTypedValue(
              pos,
              TypedValue(kChar, contiguous_strings + 20 * pos, 20));
        } else {
          column_vector_positional.positionalWriteTypedValue(
              pos,
              TypedValue(kChar,
                         kSampleStrings[pos],
                         std::strlen(kSampleStrings[pos]) + 1));
        }
      }
    }
  }

  EXPECT_EQ(num_sample_strings, column_vector_positional.size());
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(std::strlen(kSampleStrings[i]),
                column_vector_positional.getTypedValue(i).getAsciiStringLength());
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector_positional.getTypedValue(i).getDataPtr()));
    }
  }

  std::free(contiguous_strings);
}

TEST(ColumnVectorTest, IndirectCharTest) {
  const std::size_t num_sample_strings = sizeof(kSampleStrings) / sizeof(kSampleStrings[0]);

  // Make an IndirectColumnVector for nullable CHAR(20).
  IndirectColumnVector column_vector(TypeFactory::GetType(kChar, 20, true), num_sample_strings);
  EXPECT_FALSE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    TypedValue value(kChar,
                     kSampleStrings[i],
                     std::strlen(kSampleStrings[i]) + 1);
    // Use a NULL in place of every 5th value.
    if (i % 5 == 0) {
      value = TypedValue(kChar);
    }
    // Make some values into literals.
    if (i & 0x2) {
      value.ensureNotReference();
    }

    // Alternate between copy and move.
    if (i & 0x1) {
      column_vector.appendTypedValue(value);
    } else {
      column_vector.appendTypedValue(std::move(value));
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
      EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
    } else {
      EXPECT_STREQ(kSampleStrings[i], static_cast<const char*>(column_vector.getUntypedValue(i)));
      EXPECT_EQ(std::strlen(kSampleStrings[i]),
                column_vector.getTypedValue(i).getAsciiStringLength());
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector.getTypedValue(i).getDataPtr()));
    }
  }

  // Also try inserting in random order using positional writes.
  IndirectColumnVector column_vector_positional(TypeFactory::GetType(kChar, 20, true),
                                                num_sample_strings);
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(num_sample_strings, column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    TypedValue value(kChar,
                     kSampleStrings[pos],
                     std::strlen(kSampleStrings[pos]) + 1);
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      value = TypedValue(kChar);
    }
    // Make some values into literals.
    if (pos & 0x2) {
      value.ensureNotReference();
    }

    // Alternate between copy and move.
    if (pos & 0x1) {
      column_vector_positional.positionalWriteTypedValue(pos, value);
    } else {
      column_vector_positional.positionalWriteTypedValue(pos, std::move(value));
    }
  }

  EXPECT_EQ(num_sample_strings, column_vector_positional.size());
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(std::strlen(kSampleStrings[i]),
                column_vector_positional.getTypedValue(i).getAsciiStringLength());
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector_positional.getTypedValue(i).getDataPtr()));
    }
  }
}

TEST(ColumnVectorTest, IndirectVarcharTest) {
  const std::size_t num_sample_strings = sizeof(kSampleStrings) / sizeof(kSampleStrings[0]);

  // Make an IndirectColumnVector for nullable VARCHAR(20).
  IndirectColumnVector column_vector(TypeFactory::GetType(kVarChar, 20, true), num_sample_strings);
  EXPECT_FALSE(column_vector.isNative());
  EXPECT_EQ(0u, column_vector.size());

  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    TypedValue value(kVarChar,
                     kSampleStrings[i],
                     std::strlen(kSampleStrings[i]) + 1);
    // Use a NULL in place of every 5th value.
    if (i % 5 == 0) {
      value = TypedValue(kVarChar);
    }
    // Make some values into literals.
    if (i & 0x2) {
      value.ensureNotReference();
    }

    // Alternate between copy and move.
    if (i & 0x1) {
      column_vector.appendTypedValue(value);
    } else {
      column_vector.appendTypedValue(std::move(value));
    }
    EXPECT_EQ(i + 1, column_vector.size());
  }

  // Check that values are as expected using both typed and untyped interface.
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
      EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
    } else {
      EXPECT_STREQ(kSampleStrings[i], static_cast<const char*>(column_vector.getUntypedValue(i)));
      EXPECT_EQ(std::strlen(kSampleStrings[i]),
                column_vector.getTypedValue(i).getAsciiStringLength());
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector.getTypedValue(i).getDataPtr()));
    }
  }

  // Also try inserting in random order using positional writes.
  IndirectColumnVector column_vector_positional(TypeFactory::GetType(kVarChar, 20, true),
                                                num_sample_strings);
  column_vector_positional.prepareForPositionalWrites();
  EXPECT_EQ(num_sample_strings, column_vector_positional.size());

  std::vector<std::size_t> insert_order;
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    insert_order.push_back(i);
  }
  std::random_shuffle(insert_order.begin(), insert_order.end());
  for (const std::size_t pos : insert_order) {
    TypedValue value(kVarChar,
                     kSampleStrings[pos],
                     std::strlen(kSampleStrings[pos]) + 1);
    // Use a NULL in place of every 5th value.
    if (pos % 5 == 0) {
      value = TypedValue(kVarChar);
    }
    // Make some values into literals.
    if (pos & 0x2) {
      value.ensureNotReference();
    }

    // Alternate between copy and move.
    if (pos & 0x1) {
      column_vector_positional.positionalWriteTypedValue(pos, value);
    } else {
      column_vector_positional.positionalWriteTypedValue(pos, std::move(value));
    }
  }

  EXPECT_EQ(num_sample_strings, column_vector_positional.size());
  for (std::size_t i = 0; i < num_sample_strings; ++i) {
    if (i % 5 == 0) {
      EXPECT_EQ(nullptr, column_vector_positional.getUntypedValue(i));
      EXPECT_TRUE(column_vector_positional.getTypedValue(i).isNull());
    } else {
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector_positional.getUntypedValue(i)));
      EXPECT_EQ(std::strlen(kSampleStrings[i]),
                column_vector_positional.getTypedValue(i).getAsciiStringLength());
      EXPECT_STREQ(kSampleStrings[i],
                   static_cast<const char*>(column_vector_positional.getTypedValue(i).getDataPtr()));
    }
  }
}

TEST(ColumnVectorTest, NativeNullTypeTest) {
  const Type &null_type = TypeFactory::GetType(kNullType, true);
  NativeColumnVector column_vector(null_type, 100);

  for (std::size_t i = 0; i < 100; ++i) {
    if (i % 2) {
      column_vector.appendNullValue();
    } else {
      column_vector.appendTypedValue(null_type.makeNullValue());
    }
  }
  ASSERT_EQ(100u, column_vector.size());

  for (std::size_t i = 0; i < 100; ++i) {
    EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
    EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
  }
}

TEST(ColumnVectorTest, IndirectNullTypeTest) {
  const Type &null_type = TypeFactory::GetType(kNullType, true);
  IndirectColumnVector column_vector(null_type, 100);

  for (std::size_t i = 0; i < 100; ++i) {
    column_vector.appendTypedValue(null_type.makeNullValue());
  }
  ASSERT_EQ(100u, column_vector.size());

  for (std::size_t i = 0; i < 100; ++i) {
    EXPECT_EQ(nullptr, column_vector.getUntypedValue(i));
    EXPECT_TRUE(column_vector.getTypedValue(i).isNull());
  }
}

}  // namespace quickstep
