26 const auto in_arg = expr->
get_arg();
28 throw std::runtime_error(
"IN not supported for unnested expressions");
31 CHECK(expr_ti.is_boolean());
32 const auto lhs_lvs =
codegen(in_arg,
true, co);
33 llvm::Value*
result{
nullptr};
34 if (expr_ti.get_notnull()) {
44 if (in_vals_bitmap->isEmpty()) {
45 return in_vals_bitmap->hasNull()
54 if (expr_ti.get_notnull()) {
75 const auto in_arg = in_integer_set->
get_arg();
77 throw std::runtime_error(
"IN not supported for unnested expressions");
84 throw std::runtime_error(
85 "IN subquery with many right-hand side values not supported when literal "
86 "hoisting is disabled");
88 auto in_vals_bitmap = std::make_unique<InValuesBitmap>(
96 const auto& in_integer_set_ti = in_integer_set->
get_type_info();
97 CHECK(in_integer_set_ti.is_boolean());
98 const auto lhs_lvs =
codegen(in_arg,
true, co);
99 llvm::Value*
result{
nullptr};
100 if (in_integer_set_ti.get_notnull()) {
107 CHECK_EQ(
size_t(1), lhs_lvs.size());
117 const auto val_count = value_list.size();
119 if (!(ti.is_integer() || (ti.is_string() && ti.get_compression() ==
kENCODING_DICT))) {
124 ?
executor()->getStringDictionaryProxy(
125 ti.getStringDictKey(),
executor()->getRowSetMemoryOwner(),
true)
128 using ListIterator = decltype(value_list.begin());
129 std::vector<int64_t> values;
131 const int worker_count = val_count > 10000 ?
cpu_threads() : int(1);
132 std::vector<std::vector<int64_t>> values_set(worker_count, std::vector<int64_t>());
133 std::vector<std::future<bool>> worker_threads;
134 auto start_it = value_list.begin();
137 stride = (val_count + worker_count - 1) / worker_count;
138 i < val_count && start_val < val_count;
139 ++i, start_val += stride, std::advance(start_it, stride)) {
140 auto end_it = start_it;
141 std::advance(end_it, std::min(stride, val_count - start_val));
142 const auto do_work = [&](std::vector<int64_t>& out_vals,
143 const ListIterator start,
144 const ListIterator end) ->
bool {
145 for (
auto val_it = start; val_it != end; ++val_it) {
146 const auto& in_val = *val_it;
147 const auto in_val_const =
154 if (ti.is_string()) {
156 const auto string_id =
157 in_val_const->get_is_null()
159 : sdp->getIdOfString(*in_val_const->get_constval().stringval);
161 out_vals.push_back(string_id);
170 if (worker_count > 1) {
174 do_work(std::ref(values), start_it, end_it);
178 for (
auto& worker : worker_threads) {
179 success &= worker.get();
184 if (worker_count > 1) {
185 size_t total_val_count = 0;
186 for (
auto& vals : values_set) {
187 total_val_count += vals.size();
189 values.reserve(total_val_count);
190 for (
auto& vals : values_set) {
191 values.insert(values.end(), vals.begin(), vals.end());
195 return std::make_unique<InValuesBitmap>(values,
const std::vector< int64_t > & get_value_list() const
llvm::IRBuilder ir_builder_
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
future< Result > async(Fn &&fn, Args &&...args)
llvm::LLVMContext & context_
static constexpr int32_t INVALID_STR_ID
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
const SQLTypeInfo & get_type_info() const
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
static llvm::ConstantInt * codegenIntConst(const Analyzer::Constant *constant, CgenState *cgen_state)
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
llvm::Value * toBool(llvm::Value *)
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
llvm::ConstantInt * llInt(const T v) const
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::unique_ptr< InValuesBitmap > createInValuesBitmap(const Analyzer::InValues *, const CompilationOptions &)
bool is_unnest(const Analyzer::Expr *expr)
const Expr * get_arg() const
const Expr * get_arg() const
SQLTypeInfo get_nullable_type_info(const SQLTypeInfo &type_info)
Executor * executor() const