<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// varbinary_type.cpp
//
// Identification: src/codegen/type/varbinary_type.cpp
//
// Copyright (c) 2015-2017, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "codegen/type/varbinary_type.h"

#include "codegen/value.h"
#include "codegen/proxy/values_runtime_proxy.h"
#include "codegen/type/boolean_type.h"
#include "codegen/type/integer_type.h"
#include "common/exception.h"
#include "type/limits.h"

namespace peloton {
namespace codegen {
namespace type {

namespace {

///===--------------------------------------------------------------------===///
///
/// All right, this VARBINARY type is a giant hack. I admit it. It's copy-pasta
/// of VARCHAR. But, we don't have much support for it in the system overall, so
/// I'll leave the minimum required functionality here. When we start
/// implementing VARBINARY stuff, we will need to modify this.
///
///===--------------------------------------------------------------------===///

// Comparison
struct CompareVarbinary : public TypeSystem::SimpleComparisonHandleNull {
  bool SupportsTypes(const type::Type &left_type,
                     const type::Type &right_type) const override {
    return left_type.GetSqlType() == Varbinary::Instance() &&
           left_type == right_type;
  }

  // Call ValuesRuntime::CompareStrings(). This function behaves like strcmp(),
  // returning a values less than, equal to, or greater than zero if left is
  // found to be less than, matches, or is greater than the right value.
  llvm::Value *CallCompareStrings(CodeGen &codegen, const Value &left,
                                  const Value &right) const {
    // Setup the function arguments and invoke the call
    std::vector<llvm::Value *> args = {left.GetValue(), left.GetLength(),
                                       right.GetValue(), right.GetLength()};
    return codegen.Call(ValuesRuntimeProxy::CompareStrings, args);
  }

  Value CompareLtImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Check if the result is < 0
    result = codegen->CreateICmpSLT(result, codegen.Const32(0));

    // Return the comparison
    return Value{Boolean::Instance(), result};
  }

  Value CompareLteImpl(CodeGen &codegen, const Value &left,
                       const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Check if the result is <= 0
    result = codegen->CreateICmpSLE(result, codegen.Const32(0));

    // Return the comparison
    return Value{Boolean::Instance(), result};
  }

  Value CompareEqImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Check if the result is == 0
    result = codegen->CreateICmpEQ(result, codegen.Const32(0));

    // Return the comparison
    return Value{Boolean::Instance(), result};
  }

  Value CompareNeImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Check if the result is == 0
    result = codegen->CreateICmpNE(result, codegen.Const32(0));

    // Return the comparison
    return Value{Boolean::Instance(), result};
  }

  Value CompareGtImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Check if the result is > 0
    result = codegen->CreateICmpSGT(result, codegen.Const32(0));

    // Return the comparison
    return Value{Boolean::Instance(), result};
  }

  Value CompareGteImpl(CodeGen &codegen, const Value &left,
                       const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Check if the result is >= 0
    result = codegen->CreateICmpSGE(result, codegen.Const32(0));

    // Return the comparison
    return Value{Boolean::Instance(), result};
  }

  Value CompareForSortImpl(CodeGen &codegen, const Value &left,
                           const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));

    // Call CompareStrings(...)
    llvm::Value *result = CallCompareStrings(codegen, left, right);

    // Return the comparison
    return Value{Integer::Instance(), result};
  }
};<commit_msg>Fixed varbinary type to use an expensive comparison function to force null checking<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// varbinary_type.cpp
//
// Identification: src/codegen/type/varbinary_type.cpp
//
// Copyright (c) 2015-2017, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "codegen/type/varbinary_type.h"

#include "codegen/value.h"
#include "codegen/proxy/values_runtime_proxy.h"
#include "codegen/type/boolean_type.h"
#include "codegen/type/integer_type.h"
#include "common/exception.h"
#include "type/limits.h"

namespace peloton {
namespace codegen {
namespace type {

namespace {

///===--------------------------------------------------------------------===///
///
/// All right, this VARBINARY type is a giant hack. I admit it. It's copy-pasta
/// of VARCHAR. But, we don't have much support for it in the system overall, so
/// I'll leave the minimum required functionality here. When we start
/// implementing VARBINARY stuff, we will need to modify this.
///
///===--------------------------------------------------------------------===///

// Comparison
struct CompareVarbinary : public TypeSystem::ExpensiveComparisonHandleNull {
  bool SupportsTypes(const type::Type &left_type,
                     const type::Type &right_type) const override {
    return left_type.GetSqlType() == Varbinary::Instance() &&
           left_type == right_type;
  }

  // Call ValuesRuntime::CompareStrings(). This function behaves like strcmp(),
  // returning a values less than, equal to, or greater than zero if left is
  // found to be less than, matches, or is greater than the right value.
  llvm::Value *CompareStrings(CodeGen &codegen, const Value &left,
                              const Value &right) const {
    // Setup the function arguments and invoke the call
    std::vector<llvm::Value *> args = {left.GetValue(), left.GetLength(),
                                       right.GetValue(), right.GetLength()};
    return codegen.Call(ValuesRuntimeProxy::CompareStrings, args);
  }

  Value CompareLtImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, check is result is < 0
    llvm::Value *result = CompareStrings(codegen, left, right);
    llvm::Value *is_lt_0 = codegen->CreateICmpSLT(result, codegen.Const32(0));
    return Value{Boolean::Instance(), is_lt_0};
  }

  Value CompareLteImpl(CodeGen &codegen, const Value &left,
                       const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, check is result is <= 0
    llvm::Value *result = CompareStrings(codegen, left, right);
    llvm::Value *is_lte_0 = codegen->CreateICmpSLE(result, codegen.Const32(0));
    return Value{Boolean::Instance(), is_lte_0};
  }

  Value CompareEqImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, check is result is == 0
    llvm::Value *result = CompareStrings(codegen, left, right);
    llvm::Value *is_eq_0 = codegen->CreateICmpEQ(result, codegen.Const32(0));
    return Value{Boolean::Instance(), is_eq_0};
  }

  Value CompareNeImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, check is result is != 0
    llvm::Value *result = CompareStrings(codegen, left, right);
    llvm::Value *is_ne_0 = codegen->CreateICmpNE(result, codegen.Const32(0));
    return Value{Boolean::Instance(), is_ne_0};
  }

  Value CompareGtImpl(CodeGen &codegen, const Value &left,
                      const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, check is result is <= 0
    llvm::Value *result = CompareStrings(codegen, left, right);
    llvm::Value *is_gt_0 = codegen->CreateICmpSGT(result, codegen.Const32(0));
    return Value{Boolean::Instance(), is_gt_0};
  }

  Value CompareGteImpl(CodeGen &codegen, const Value &left,
                       const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, check is result is >= 0
    llvm::Value *result = CompareStrings(codegen, left, right);
    llvm::Value *is_gte_0 = codegen->CreateICmpSGE(result, codegen.Const32(0));
    return Value{Boolean::Instance(), is_gte_0};
  }

  Value CompareForSortImpl(CodeGen &codegen, const Value &left,
                           const Value &right) const override {
    PL_ASSERT(SupportsTypes(left.GetType(), right.GetType()));
    // Call CompareStrings, return result directly
    llvm::Value *result = CompareStrings(codegen, left, right);
    return Value{Integer::Instance(), result};
  }
};
{'fraction_non_alphanumeric': 0.17613745440583606, 'fraction_numerical': 0.007295066231522365, 'mean_word_length': 2.5791824115424253, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1063203', 'n_tokens_mistral': 2897, 'n_tokens_neox': 2784, 'n_words': 790}