/**
 * 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.
 **/

// NOTE(chasseur): This file helps resolve some otherwise intractible circular
// dependencies with the the vectorized methods of the template classes in
// LiteralComparators.hpp. It should ONLY be included where a
// LiteralUncheckedComparator is actually created (e.g. the various
// comparison source files like LessComparison.cpp, and ComparisonUtil.hpp).

#ifndef QUICKSTEP_TYPES_OPERATIONS_COMPARISONS_LITERAL_COMPARATORS_INL_HPP_
#define QUICKSTEP_TYPES_OPERATIONS_COMPARISONS_LITERAL_COMPARATORS_INL_HPP_

#include <cstddef>
#include <memory>
#include <type_traits>

#include "catalog/CatalogTypedefs.hpp"
#include "storage/TupleIdSequence.hpp"
#include "storage/ValueAccessor.hpp"
#include "storage/ValueAccessorUtil.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/ColumnVector.hpp"
#include "types/operations/comparisons/LiteralComparators.hpp"

#include "glog/logging.h"

namespace quickstep {

#ifdef QUICKSTEP_ENABLE_COMPARISON_INLINE_EXPANSION
template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
                                            LeftCppType, left_nullable,
                                            RightCppType, right_nullable>
    ::compareColumnVectors(
        const ColumnVector &left,
        const ColumnVector &right,
        const TupleIdSequence *filter,
        const TupleIdSequence *existence_bitmap) const {
#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
  static constexpr bool short_circuit = true;
#else
  static constexpr bool short_circuit = false;
#endif
  // All literal types are usable with NativeColumnVector.
  DCHECK(left.isNative());
  DCHECK(right.isNative());

  const NativeColumnVector &left_native = static_cast<const NativeColumnVector&>(left);
  const NativeColumnVector &right_native = static_cast<const NativeColumnVector&>(right);

  DCHECK_EQ(left_native.size(), right_native.size());
  DCHECK((existence_bitmap == nullptr)
         || (existence_bitmap->numTuples() == left_native.size()));
  DCHECK((filter == nullptr)
         || ((existence_bitmap == nullptr) ? (filter->length() == left_native.size())
                                                 : (filter->length() == existence_bitmap->length())));
  TupleIdSequence *result = new TupleIdSequence(
      (existence_bitmap == nullptr) ? left_native.size()
                                    : existence_bitmap->length());
  if (short_circuit && (filter != nullptr)) {
    if (existence_bitmap != nullptr) {
      TupleIdSequence::const_iterator existence_it = existence_bitmap->begin();
      for (std::size_t cv_pos = 0;
           cv_pos < left_native.size();
           ++cv_pos) {
        DCHECK(existence_it != existence_bitmap->end());
        result->set(*existence_it,
                    filter->get(*existence_it)
                        && compareDataPtrsInl(left_native.getUntypedValue<left_nullable>(cv_pos),
                                              right_native.getUntypedValue<right_nullable>(cv_pos)));
        ++existence_it;
      }
      DCHECK(existence_it == existence_bitmap->end());
    } else {
      for (TupleIdSequence::const_iterator filter_it = filter->begin();
           filter_it != filter->end();
           ++filter_it) {
        result->set(*filter_it,
                    compareDataPtrsInl(left_native.getUntypedValue<left_nullable>(*filter_it),
                                       right_native.getUntypedValue<right_nullable>(*filter_it)));
      }
    }
  } else {
    if (existence_bitmap != nullptr) {
      TupleIdSequence::const_iterator existence_it = existence_bitmap->begin();
      for (std::size_t cv_pos = 0;
           cv_pos < left_native.size();
           ++cv_pos) {
        DCHECK(existence_it != existence_bitmap->end());
        result->set(*existence_it,
                    compareDataPtrsInl(left_native.getUntypedValue<left_nullable>(cv_pos),
                                       right_native.getUntypedValue<right_nullable>(cv_pos)));
        ++existence_it;
      }
      DCHECK(existence_it == existence_bitmap->end());
    } else {
      for (std::size_t pos = 0;
           pos < left_native.size();
           ++pos) {
        result->set(pos,
                    compareDataPtrsInl(left_native.getUntypedValue<left_nullable>(pos),
                                       right_native.getUntypedValue<right_nullable>(pos)));
      }
    }
    if (!short_circuit && (filter != nullptr)) {
      result->intersectWith(*filter);
    }
  }

  return result;
}

template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
template <bool column_vector_on_left>
TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
                                            LeftCppType, left_nullable,
                                            RightCppType, right_nullable>
    ::compareColumnVectorAndStaticValueHelper(
        const ColumnVector &column_vector,
        const TypedValue &static_value,
        const TupleIdSequence *filter,
        const TupleIdSequence *existence_bitmap) const {
#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
  static constexpr bool short_circuit = true;
#else
  static constexpr bool short_circuit = false;
#endif
  typedef typename std::conditional<column_vector_on_left,
                                    RightCppType,
                                    LeftCppType>::type
      StaticValueCppType;

  constexpr bool cv_nullable = column_vector_on_left ? left_nullable : right_nullable;
  constexpr bool static_value_nullable = column_vector_on_left ? right_nullable : left_nullable;

  DCHECK(column_vector.isNative());
  const NativeColumnVector &native_column_vector
      = static_cast<const NativeColumnVector&>(column_vector);

  DCHECK((existence_bitmap == nullptr)
               || (existence_bitmap->numTuples() == native_column_vector.size()));
  DCHECK((filter == nullptr)
               || ((existence_bitmap == nullptr) ? (filter->length() == native_column_vector.size())
                                                 : (filter->length() == existence_bitmap->length())));
  TupleIdSequence *result = new TupleIdSequence(
      (existence_bitmap == nullptr) ? native_column_vector.size()
                                    : existence_bitmap->length());
  if (static_value_nullable && static_value.isNull()) {
    return result;
  }
  const StaticValueCppType literal = static_value.getLiteral<StaticValueCppType>();

  if (short_circuit && (filter != nullptr)) {
    if (existence_bitmap != nullptr) {
      TupleIdSequence::const_iterator existence_it = existence_bitmap->begin();
      for (std::size_t cv_pos = 0;
           cv_pos < native_column_vector.size();
           ++cv_pos) {
        DCHECK(existence_it != existence_bitmap->end());
        if (filter->get(*existence_it)) {
          const void *cv_value
              = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
          result->set(*existence_it,
                      !(cv_nullable && (cv_value == nullptr))
                          && compareDataPtrsHelper<column_vector_on_left>(cv_value, &literal));
        }
        ++existence_it;
      }
      DCHECK(existence_it == existence_bitmap->end());
    } else {
      for (TupleIdSequence::const_iterator filter_it = filter->begin();
           filter_it != filter->end();
           ++filter_it) {
        const void *cv_value
            = native_column_vector.getUntypedValue<cv_nullable>(*filter_it);
        result->set(*filter_it,
                    !(cv_nullable && (cv_value == nullptr))
                        && compareDataPtrsHelper<column_vector_on_left>(cv_value, &literal));
      }
    }
  } else {
    if (existence_bitmap != nullptr) {
      TupleIdSequence::const_iterator existence_it = existence_bitmap->begin();
      for (std::size_t cv_pos = 0;
           cv_pos < native_column_vector.size();
           ++cv_pos) {
        DCHECK(existence_it != existence_bitmap->end());
        const void *cv_value
            = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
        result->set(*existence_it,
                    !(cv_nullable && (cv_value == nullptr))
                        && compareDataPtrsHelper<column_vector_on_left>(cv_value, &literal));
        ++existence_it;
      }
      DCHECK(existence_it == existence_bitmap->end());
    } else {
      for (std::size_t pos = 0;
           pos < native_column_vector.size();
           ++pos) {
        const void *cv_value
            = native_column_vector.getUntypedValue<cv_nullable>(pos);
        result->set(pos,
                    !(cv_nullable && (cv_value == nullptr))
                        && compareDataPtrsHelper<column_vector_on_left>(cv_value, &literal));
      }
    }
    if (!short_circuit && (filter != nullptr)) {
      result->intersectWith(*filter);
    }
  }

  return result;
}

#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION

template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
                                            LeftCppType, left_nullable,
                                            RightCppType, right_nullable>
    ::compareSingleValueAccessor(
        ValueAccessor *accessor,
        const attribute_id left_id,
        const attribute_id right_id,
        const TupleIdSequence *filter) const {
  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
      accessor,
      [&](auto *accessor) -> TupleIdSequence* {  // NOLINT(build/c++11)
#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
    static constexpr bool short_circuit = true;
#else
    static constexpr bool short_circuit = false;
#endif

    TupleIdSequence *result = new TupleIdSequence(accessor->getEndPosition());
    if (short_circuit && (filter != nullptr)) {
      DCHECK_EQ(filter->length(), result->length());
      for (TupleIdSequence::const_iterator filter_it = filter->begin();
           filter_it != filter->end();
           ++filter_it) {
        const void *left_value
            = accessor->template getUntypedValueAtAbsolutePosition<left_nullable>(left_id, *filter_it);
        const void *right_value
            = accessor->template getUntypedValueAtAbsolutePosition<right_nullable>(right_id, *filter_it);
        result->set(*filter_it,
                    (!((left_nullable && (left_value == nullptr))
                        || (right_nullable && (right_value == nullptr))))
                            && this->compareDataPtrsHelper<true>(left_value, right_value));
      }
    } else {
      accessor->beginIteration();
      if (accessor->isColumnAccessorSupported()) {
        // If ColumnAccessor is supported on the underlying accessor, we have a fast strided
        // column accessor available for the iteration on the underlying block.
        std::unique_ptr<const ColumnAccessor<left_nullable>>
            left_column_accessor(accessor->template getColumnAccessor<left_nullable>(left_id));
        std::unique_ptr<const ColumnAccessor<right_nullable>>
            right_column_accessor(accessor->template getColumnAccessor<right_nullable>(right_id));
        DCHECK(left_column_accessor != nullptr);
        DCHECK(right_column_accessor != nullptr);
        while (accessor->next()) {
          const void *left_value = left_column_accessor->getUntypedValue();
          const void *right_value = right_column_accessor->getUntypedValue();
          result->set(accessor->getCurrentPosition(),
                      (!((left_nullable && (left_value == nullptr))
                          || (right_nullable && (right_value == nullptr))))
                          && this->compareDataPtrsHelper<true>(left_value, right_value));
        }
      } else {
        while (accessor->next()) {
          const void *left_value = accessor->template getUntypedValue<left_nullable>(left_id);
          const void *right_value = accessor->template getUntypedValue<right_nullable>(right_id);
          result->set(accessor->getCurrentPosition(),
                      (!((left_nullable && (left_value == nullptr))
                          || (right_nullable && (right_value == nullptr))))
                          && this->compareDataPtrsHelper<true>(left_value, right_value));
        }
      }
      if (!short_circuit && (filter != nullptr)) {
        result->intersectWith(*filter);
      }
    }

    return result;
  });
}

template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
template <bool value_accessor_on_left>
TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
                                            LeftCppType, left_nullable,
                                            RightCppType, right_nullable>
    ::compareValueAccessorAndStaticValueHelper(
        ValueAccessor *accessor,
        const attribute_id value_accessor_attr_id,
        const TypedValue &static_value,
        const TupleIdSequence *filter) const {
  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
      accessor,
      [&](auto *accessor) -> TupleIdSequence* {  // NOLINT(build/c++11)
#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
    static constexpr bool short_circuit = true;
#else
    static constexpr bool short_circuit = false;
#endif
    typedef typename std::conditional<value_accessor_on_left,
                                      RightCppType,
                                      LeftCppType>::type
        StaticValueCppType;

    constexpr bool va_nullable = value_accessor_on_left ? left_nullable : right_nullable;
    constexpr bool static_value_nullable = value_accessor_on_left ? right_nullable : left_nullable;

    TupleIdSequence *result = new TupleIdSequence(accessor->getEndPosition());
    if (static_value_nullable && static_value.isNull()) {
      return result;
    }
    const StaticValueCppType literal = static_value.getLiteral<StaticValueCppType>();

    if (short_circuit && (filter != nullptr)) {
      DCHECK_EQ(filter->length(), result->length());
      for (TupleIdSequence::const_iterator filter_it = filter->begin();
           filter_it != filter->end();
           ++filter_it) {
        const void *va_value
            = accessor->template getUntypedValueAtAbsolutePosition<va_nullable>(
                value_accessor_attr_id,
                *filter_it);
        result->set(*filter_it,
                    !(va_nullable && (va_value == nullptr))
                        && this->compareDataPtrsHelper<value_accessor_on_left>(va_value, &literal));
      }
    } else {
      accessor->beginIteration();
      if (accessor->isColumnAccessorSupported()) {
        // If ColumnAccessor is supported on the underlying accessor, we have a fast strided
        // column accessor available for the iteration on the underlying block.
        std::unique_ptr<const ColumnAccessor<va_nullable>>
            column_accessor(accessor->template getColumnAccessor<va_nullable>(value_accessor_attr_id));
        DCHECK(column_accessor != nullptr);
        while (accessor->next()) {
          const void *va_value = column_accessor->getUntypedValue();
          result->set(accessor->getCurrentPosition(),
                      !(va_nullable && (va_value == nullptr))
                          && this->compareDataPtrsHelper<value_accessor_on_left>(va_value, &literal));
        }
      } else {
        while (accessor->next()) {
          const void *va_value
              = accessor->template getUntypedValue<va_nullable>(value_accessor_attr_id);
          result->set(accessor->getCurrentPosition(),
                      !(va_nullable && (va_value == nullptr))
                          && this->compareDataPtrsHelper<value_accessor_on_left>(va_value,
                                                                                 &literal));
        }
      }
      if (!short_circuit && (filter != nullptr)) {
        result->intersectWith(*filter);
      }
    }

    return result;
  });
}

template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
template <bool column_vector_on_left>
TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
                                            LeftCppType, left_nullable,
                                            RightCppType, right_nullable>
    ::compareColumnVectorAndValueAccessorHelper(
        const ColumnVector &column_vector,
        ValueAccessor *accessor,
        const attribute_id value_accessor_attr_id,
        const TupleIdSequence *filter,
        const TupleIdSequence *existence_bitmap) const {
  DCHECK(column_vector.isNative());
  const NativeColumnVector &native_column_vector
      = static_cast<const NativeColumnVector&>(column_vector);

  DCHECK((existence_bitmap == nullptr)
               || (existence_bitmap->numTuples() == native_column_vector.size()));
  DCHECK((filter == nullptr)
               || ((existence_bitmap == nullptr) ? (filter->length() == native_column_vector.size())
                                                 : (filter->length() == existence_bitmap->length())));
  TupleIdSequence *result = new TupleIdSequence(
      (existence_bitmap == nullptr) ? native_column_vector.size()
                                    : existence_bitmap->length());

  InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
      accessor,
      [&](auto *accessor) -> void {  // NOLINT(build/c++11)
#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
    static constexpr bool short_circuit = true;
#else
    static constexpr bool short_circuit = false;
#endif
    constexpr bool cv_nullable = column_vector_on_left ? left_nullable : right_nullable;
    constexpr bool va_nullable = column_vector_on_left ? right_nullable : left_nullable;

    DCHECK_EQ(native_column_vector.size(),
              static_cast<size_t>(accessor->getNumTuples()));
    if (short_circuit && (filter != nullptr)) {
      DCHECK_EQ(filter->length(), result->length());
      if (existence_bitmap != nullptr) {
        TupleIdSequence::const_iterator existence_it = existence_bitmap->begin();
        for (std::size_t cv_pos = 0;
             cv_pos < native_column_vector.size();
             ++cv_pos) {
          DCHECK(existence_it != existence_bitmap->end());
          if (filter->get(*existence_it)) {
            const void *cv_value
                = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
            const void *va_value
                = accessor->template getUntypedValueAtAbsolutePosition<va_nullable>(
                    value_accessor_attr_id,
                    *existence_it);
            result->set(*existence_it,
                        (!((cv_nullable && (cv_value == nullptr))
                            || (va_nullable && (va_value == nullptr))))
                                && this->compareDataPtrsHelper<column_vector_on_left>(cv_value, va_value));
          }
          ++existence_it;
        }
        DCHECK(existence_it == existence_bitmap->end());
      } else {
        for (TupleIdSequence::const_iterator filter_it = filter->begin();
             filter_it != filter->end();
             ++filter_it) {
          const void *cv_value
              = native_column_vector.getUntypedValue<cv_nullable>(*filter_it);
          const void *va_value
              = accessor->template getUntypedValueAtAbsolutePosition<va_nullable>(
                  value_accessor_attr_id,
                  *filter_it);
          result->set(*filter_it,
                      (!((cv_nullable && (cv_value == nullptr))
                          || (va_nullable && (va_value == nullptr))))
                              && this->compareDataPtrsHelper<column_vector_on_left>(cv_value, va_value));
        }
      }
    } else {
      if (existence_bitmap != nullptr) {
        TupleIdSequence::const_iterator existence_it = existence_bitmap->begin();
        for (std::size_t cv_pos = 0;
             cv_pos < native_column_vector.size();
             ++cv_pos) {
          DCHECK(existence_it != existence_bitmap->end());

          const void *cv_value
              = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
          const void *va_value
              = accessor->template getUntypedValueAtAbsolutePosition<va_nullable>(
                  value_accessor_attr_id,
                  *existence_it);
          result->set(*existence_it,
                      (!((cv_nullable && (cv_value == nullptr))
                          || (va_nullable && (va_value == nullptr))))
                              && this->compareDataPtrsHelper<column_vector_on_left>(cv_value, va_value));

          ++existence_it;
        }
        DCHECK(existence_it == existence_bitmap->end());
      } else {
        accessor->beginIteration();
        std::size_t cv_pos = 0;
        if (accessor->isColumnAccessorSupported()) {
          // If ColumnAccessor is supported on the underlying accessor, we have a fast strided
          // column accessor available for the iteration on the underlying block.
          std::unique_ptr<const ColumnAccessor<va_nullable>>
              column_accessor(accessor->template getColumnAccessor<va_nullable>(value_accessor_attr_id));
          DCHECK(column_accessor != nullptr);
          while (accessor->next()) {
            const void *cv_value
                = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
            const void *va_value = column_accessor->getUntypedValue();
            result->set(cv_pos,
                        (!((cv_nullable && (cv_value == nullptr))
                            || (va_nullable && (va_value == nullptr))))
                            && this->compareDataPtrsHelper<column_vector_on_left>(cv_value,
                                                                                  va_value));
            ++cv_pos;
          }
        } else {
          while (accessor->next()) {
            const void *cv_value
                = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
            const void *va_value
                = accessor->template getUntypedValue<va_nullable>(value_accessor_attr_id);
            result->set(cv_pos,
                        (!((cv_nullable && (cv_value == nullptr))
                            || (va_nullable && (va_value == nullptr))))
                            && this->compareDataPtrsHelper<column_vector_on_left>(cv_value,
                                                                                  va_value));
            ++cv_pos;
          }
        }
      }
      if (!short_circuit && (filter != nullptr)) {
        result->intersectWith(*filter);
      }
    }
  });

  return result;
}

template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
TypedValue LiteralUncheckedComparator<ComparisonFunctor,
                                      LeftCppType, left_nullable,
                                      RightCppType, right_nullable>
    ::accumulateValueAccessor(
        const TypedValue &current,
        ValueAccessor *accessor,
        const attribute_id value_accessor_id) const {
  bool is_null = current.isNull();
  LeftCppType current_literal;
  if (!is_null) {
    current_literal = current.getLiteral<LeftCppType>();
  }

  InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
      accessor,
      [&](auto *accessor) -> void {  // NOLINT(build/c++11)
    accessor->beginIteration();
    if (accessor->isColumnAccessorSupported()) {
      // If ColumnAccessor is supported on the underlying accessor, we have a fast strided
      // column accessor available for the iteration on the underlying block.
      std::unique_ptr<const ColumnAccessor<left_nullable>>
          column_accessor(accessor->template getColumnAccessor<left_nullable>(value_accessor_id));
      DCHECK(column_accessor != nullptr);

      // Locate the first non-null value.
      if (is_null) {
        const void *va_value = nullptr;
        while (accessor->next()) {
          va_value = column_accessor->getUntypedValue();
          if (!left_nullable || va_value) {
            break;
          }
        }
        if (va_value != nullptr) {
          is_null = false;
          current_literal = *static_cast<const LeftCppType*>(va_value);
        }
      }

      // Aggregate on the remaining values.
      if (!accessor->iterationFinished()) {
        DCHECK(!is_null);
        while (accessor->next()) {
          const void *va_value = column_accessor->getUntypedValue();
          if (left_nullable && !va_value) {
            continue;
          }
          if (this->compareDataPtrsHelper<true>(va_value, &current_literal)) {
            current_literal = *static_cast<const LeftCppType*>(va_value);
          }
        }
      }
    } else {
      // Locate the first non-null value.
      if (is_null) {
        const void *va_value = nullptr;
        while (accessor->next()) {
          va_value = accessor->template getUntypedValue<left_nullable>(value_accessor_id);
          if (!left_nullable || va_value) {
            break;
          }
        }
        if (va_value != nullptr) {
          is_null = false;
          current_literal = *static_cast<const LeftCppType*>(va_value);
        }
      }

      // Aggregate on the remaining values.
      if (!accessor->iterationFinished()) {
        DCHECK(!is_null);
        while (accessor->next()) {
          const void *va_value =
              accessor->template getUntypedValue<left_nullable>(value_accessor_id);
          if (left_nullable && !va_value) {
            continue;
          }
          if (this->compareDataPtrsHelper<true>(va_value, &current_literal)) {
            current_literal = *static_cast<const LeftCppType*>(va_value);
          }
        }
      }
    }
  });

  if (is_null) {
    return TypedValue(current.getTypeID());
  } else {
    return TypedValue(current_literal);
  }
}

#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION

template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
          typename LeftCppType, bool left_nullable,
          typename RightCppType, bool right_nullable>
TypedValue LiteralUncheckedComparator<ComparisonFunctor,
                                      LeftCppType, left_nullable,
                                      RightCppType, right_nullable>
    ::accumulateColumnVector(
        const TypedValue &current,
        const ColumnVector &column_vector) const {
  const void *current_literal = current.isNull() ? nullptr : current.getDataPtr();

  // All literal types are usable with NativeColumnVector.
  DCHECK(column_vector.isNative());

  const NativeColumnVector &native_vector = static_cast<const NativeColumnVector&>(column_vector);
  for (std::size_t pos = 0; pos < native_vector.size(); ++pos) {
    const void *cv_value = native_vector.getUntypedValue<left_nullable>(pos);
    if (left_nullable && !cv_value) {
      continue;
    }
    if (!current_literal || compareDataPtrsHelper<true>(cv_value, current_literal)) {
      current_literal = cv_value;
    }
  }

  if (current_literal) {
    return TypedValue(*static_cast<const LeftCppType*>(current_literal));
  } else {
    return TypedValue(current.getTypeID());
  }
}
#endif  // QUICKSTEP_ENABLE_COMPARISON_INLINE_EXPANSION

}  // namespace quickstep

#endif  // QUICKSTEP_TYPES_OPERATIONS_COMPARISONS_LITERAL_COMPARATORS_INL_HPP_
