20 #include "../Shared/funcannotations.h"
21 #include "../Shared/sqldefs.h"
26 #include <boost/locale/conversion.hpp>
29 auto chunk_iter =
reinterpret_cast<ChunkIter*
>(chunk_iter_);
39 const int64_t string_dict_handle) {
43 auto string_dict_proxy =
46 CHECK(string_bytes.first);
47 return {string_bytes.first, string_bytes.second};
51 const int64_t string_dict_handle) {
52 std::string_view
const sv = string_view.
stringView();
54 return inline_int_null_value<int32_t>();
62 const int32_t str_len,
63 const int64_t string_ops_handle,
64 const int64_t string_dict_handle) {
65 std::string raw_str(str_ptr, str_len);
67 reinterpret_cast<const StringOps_Namespace::StringOps*
>(string_ops_handle);
69 const auto result_str = string_ops->operator()(raw_str);
70 if (result_str.empty()) {
71 return inline_int_null_value<int32_t>();
78 const int32_t str1_len,
80 const int32_t str2_len,
81 const int64_t string_ops_handle,
82 const int64_t string_dict_handle) {
83 std::string_view raw_str1(str1_ptr, str1_len);
84 std::string_view raw_str2(str2_ptr, str2_len);
86 reinterpret_cast<const StringOps_Namespace::StringOps*
>(string_ops_handle);
88 const auto result_str = string_ops->multi_input_eval(raw_str1, raw_str2);
89 if (result_str.empty()) {
90 return inline_int_null_value<int32_t>();
97 const int64_t source_string_dict_handle,
98 const int64_t dest_string_dict_handle) {
99 const auto source_string_dict_proxy =
101 auto dest_string_dict_proxy =
104 const auto source_str = source_string_dict_proxy->
getString(string_id);
105 if (source_str.empty()) {
106 return inline_int_null_value<int32_t>();
108 return dest_string_dict_proxy->getIdOfString(source_str);
113 const int64_t source_string_dict_handle,
114 const int64_t dest_string_dict_handle) {
115 const auto source_string_dict_proxy =
117 auto dest_string_dict_proxy =
120 const auto source_str = source_string_dict_proxy->
getString(string_id);
121 if (source_str.empty()) {
122 return inline_int_null_value<int32_t>();
124 return dest_string_dict_proxy->getOrAddTransient(source_str);
127 #define DEF_APPLY_NUMERIC_STRING_OPS(value_type, value_name) \
128 extern "C" RUNTIME_EXPORT ALWAYS_INLINE value_type \
129 apply_numeric_string_ops_##value_name( \
130 const char* str_ptr, const int32_t str_len, const int64_t string_ops_handle) { \
131 const std::string_view raw_str(str_ptr, str_len); \
133 reinterpret_cast<const StringOps_Namespace::StringOps*>(string_ops_handle); \
134 const auto result_datum = string_ops->numericEval(raw_str); \
135 return result_datum.value_name##val; \
146 #undef DEF_APPLY_NUMERIC_STRING_OPS
148 #define DEF_APPLY_MULTI_INPUT_NUMERIC_STRING_OPS(value_type, value_name) \
149 extern "C" RUNTIME_EXPORT ALWAYS_INLINE value_type \
150 apply_multi_input_numeric_string_ops_##value_name( \
151 const char* str1_ptr, \
152 const int32_t str1_len, \
153 const char* str2_ptr, \
154 const int32_t str2_len, \
155 const int64_t string_ops_handle) { \
156 const std::string_view raw_str1(str1_ptr, str1_len); \
157 const std::string_view raw_str2(str2_ptr, str2_len); \
159 reinterpret_cast<const StringOps_Namespace::StringOps*>(string_ops_handle); \
160 const auto result_datum = string_ops->numericEval(raw_str1, raw_str2); \
161 return result_datum.value_name##val; \
166 #undef DEF_APPLY_MULTI_INPUT_NUMERIC_STRING_OPS
169 const int64_t string_dict_handle) {
171 return inline_int_null_value<int32_t>();
177 #define DEF_CONVERT_TO_STRING_AND_ENCODE(value_type, value_name) \
178 extern "C" RUNTIME_EXPORT ALWAYS_INLINE int32_t \
179 convert_to_string_and_encode_##value_name(const value_type operand, \
180 const int64_t string_dict_handle) { \
181 return write_string_to_proxy(std::to_string(operand), string_dict_handle); \
191 #undef DEF_CONVERT_TO_STRING_AND_ENCODE
195 const int64_t string_dict_handle) {
201 const int32_t precision,
203 const int64_t string_dict_handle) {
204 constexpr
size_t buf_size = 64;
207 snprintf(buf, buf_size,
"%*.*f", precision, scale, v);
213 const int64_t string_dict_handle) {
214 constexpr
size_t buf_size = 64;
222 const int32_t dimension,
223 const int64_t string_dict_handle) {
224 constexpr
size_t buf_size = 64;
232 const int64_t string_dict_handle) {
233 constexpr
size_t buf_size = 64;
243 if (str_lv.size() != 3) {
253 std::vector<llvm::Value*> charlength_args{str_lv[1], str_lv[2]};
254 std::string fn_name(
"char_length");
256 fn_name +=
"_encoded";
260 fn_name +=
"_nullable";
279 std::vector<StringOps_Namespace::StringOpInfo> string_op_infos;
281 if (chained_string_op_exprs.empty()) {
285 throw std::runtime_error(
286 "Expected folded string operator but found operator unfolded.");
289 for (
const auto& chained_string_op_expr : chained_string_op_exprs) {
290 auto chained_string_op =
292 CHECK(chained_string_op);
294 chained_string_op->get_type_info(),
295 chained_string_op->getLiteralArgs());
296 string_op_infos.emplace_back(string_op_info);
298 return string_op_infos;
301 std::pair<std::vector<llvm::Value*>, std::unique_ptr<CodeGenerator::NullCheckCodegen>>
304 const size_t arg_idx,
305 const bool codegen_nullcheck) {
309 auto primary_str_lv =
codegen(expr->
getArg(arg_idx),
true, co);
310 std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
311 if (primary_str_lv.size() != 3 && arg_ti.is_dict_encoded_string()) {
315 CHECK_EQ(
size_t(1), primary_str_lv.size());
316 const bool is_nullable = !arg_ti.get_notnull();
317 if (codegen_nullcheck && is_nullable) {
319 nullcheck_codegen = std::make_unique<CodeGenerator::NullCheckCodegen>(
324 "transient_dict_per_row_nullcheck");
326 const auto sdp_ptr =
reinterpret_cast<int64_t
>(
executor()->getStringDictionaryProxy(
327 arg_ti.getStringDictKey(),
executor()->getRowSetMemoryOwner(),
true));
328 const auto string_view =
336 }
else if (primary_str_lv.size() == 1 and arg_ti.is_none_encoded_string()) {
338 CHECK(primary_str_lv[0]->getType()->isPointerTy());
340 primary_str_lv[0]->getType()->getPointerElementType(), primary_str_lv[0]);
341 primary_str_lv.push_back(
347 CHECK_EQ(
size_t(3), primary_str_lv.size());
348 return std::make_pair(primary_str_lv, std::move(nullcheck_codegen));
359 if (
g_cluster && return_ti.is_dict_encoded_string()) {
360 throw std::runtime_error(
361 "Cast from none-encoded string to dictionary-encoded not supported for "
362 "distributed queries");
367 const auto [primary_str_lv, nullcheck_codegen] =
369 CHECK_EQ(
size_t(3), primary_str_lv.size());
372 CHECK(string_op_infos.size());
374 const auto string_ops =
375 executor()->getRowSetMemoryOwner()->getStringOps(string_op_infos);
376 const int64_t string_ops_handle =
reinterpret_cast<int64_t
>(string_ops);
379 if (!return_ti.is_string()) {
382 std::vector<llvm::Value*> string_oper_lvs;
383 if (non_literals_arity == 1UL) {
384 string_oper_lvs = {primary_str_lv[1], primary_str_lv[2], string_ops_handle_lv};
386 const auto [secondary_str_lv, secondary_nullcheck_codegen] =
388 CHECK_EQ(
size_t(3), secondary_str_lv.size());
389 string_oper_lvs = {primary_str_lv[1],
393 string_ops_handle_lv};
395 const auto return_type = return_ti.get_type();
396 std::string fn_call = non_literals_arity == 1UL
397 ?
"apply_numeric_string_ops_"
398 :
"apply_multi_input_numeric_string_ops_";
399 switch (return_type) {
422 throw std::runtime_error(
"Unimplemented type for string-to-numeric translation");
425 const auto logical_size = return_ti.get_logical_size() * 8;
426 auto llvm_return_type = return_ti.is_fp()
430 if (nullcheck_codegen) {
437 CHECK(return_ti.is_dict_encoded_string());
438 const int64_t dest_string_proxy_handle =
439 reinterpret_cast<int64_t
>(
executor()->getStringDictionaryProxy(
440 return_ti.getStringDictKey(),
executor()->getRowSetMemoryOwner(),
true));
441 auto dest_string_proxy_handle_lv =
cgen_state_->
llInt(dest_string_proxy_handle);
442 if (non_literals_arity == 1UL) {
443 std::vector<llvm::Value*> string_oper_lvs{primary_str_lv[1],
445 string_ops_handle_lv,
446 dest_string_proxy_handle_lv};
451 if (nullcheck_codegen) {
467 const auto [secondary_str_lv, secondary_nullcheck_codegen] =
469 CHECK_EQ(
size_t(3), secondary_str_lv.size());
470 std::vector<llvm::Value*> string_oper_lvs{primary_str_lv[1],
474 string_ops_handle_lv,
475 dest_string_proxy_handle_lv};
479 if (secondary_nullcheck_codegen) {
483 if (nullcheck_codegen) {
493 Executor* executor) {
498 CHECK(string_op_infos.size());
500 if (string_op_infos.back().getReturnType().is_dict_encoded_string()) {
502 auto string_dictionary_translation_mgr =
503 std::make_unique<StringDictionaryTranslationMgr>(
511 executor->deviceCount(device_type),
513 executor->getDataMgr(),
515 return string_dictionary_translation_mgr;
518 auto string_dictionary_translation_mgr =
519 std::make_unique<StringDictionaryTranslationMgr>(
525 executor->deviceCount(device_type),
527 executor->getDataMgr(),
529 return string_dictionary_translation_mgr;
542 auto string_dictionary_translation_mgr =
546 CHECK_EQ(
size_t(1), str_id_lv.size());
551 ->
codegen(str_id_lv[0], expr_ti,
true , co);
559 const std::vector<StringOps_Namespace::StringOpInfo>& string_op_infos,
565 auto string_dictionary_translation_mgr =
566 std::make_unique<StringDictionaryTranslationMgr>(
579 auto str_id_lv =
codegen(expr,
true , co);
580 CHECK_EQ(
size_t(1), str_id_lv.size());
584 ->
codegen(str_id_lv[0], expr_ti,
true , co);
591 throw std::runtime_error(
"LIKE not supported for unnested expressions");
593 char escape_char{
'\\'};
595 auto escape_char_expr =
597 CHECK(escape_char_expr);
598 CHECK(escape_char_expr->get_type_info().is_string());
599 CHECK_EQ(
size_t(1), escape_char_expr->get_constval().stringval->size());
600 escape_char = (*escape_char_expr->get_constval().stringval)[0];
610 if (fast_dict_like_lv) {
611 return fast_dict_like_lv;
614 CHECK(ti.is_string());
617 "Cannot do LIKE / ILIKE on this dictionary encoded column, its cardinality is "
621 if (str_lv.size() != 3) {
632 CHECK_EQ(
size_t(3), like_expr_arg_lvs.size());
634 std::vector<llvm::Value*> str_like_args{str_lv[1],
636 like_expr_arg_lvs[1],
637 like_expr_arg_lvs[2],
639 std::string fn_name{expr->
get_is_ilike() ?
"string_ilike" :
"string_like"};
641 fn_name +=
"_simple";
644 fn_name +=
"_nullable";
651 Executor* executor) {
665 CHECK(string_oper_primary_arg_ti.is_dict_encoded_string());
672 const std::shared_ptr<Analyzer::Expr> like_arg,
675 const bool is_simple,
676 const char escape_char,
679 const auto cast_oper = std::dynamic_pointer_cast<
Analyzer::UOper>(like_arg);
685 const auto dict_like_arg = cast_oper->get_own_operand();
686 const auto& dict_like_arg_ti = dict_like_arg->get_type_info();
687 if (!dict_like_arg_ti.is_string()) {
688 throw(std::runtime_error(
"Cast from " + dict_like_arg_ti.get_type_name() +
" to " +
689 cast_oper->get_type_info().get_type_name() +
693 const auto sdp =
executor()->getStringDictionaryProxy(
694 dict_like_arg_ti.getStringDictKey(),
executor()->getRowSetMemoryOwner(),
true);
695 if (sdp->storageEntryCount() > 200000000) {
698 if (sdp->getDictKey().isTransientDict()) {
714 CHECK(pattern_ti.is_string());
717 const auto& pattern_str = *pattern_datum.
stringval;
719 const auto matching_ids =
720 sdp->getLike<int64_t>(pattern_str, ilike, is_simple, escape_char);
722 VLOG(3) <<
"Processing like operator with the pattern " << pattern_str <<
" took "
723 << work_ms <<
" ms (# matching elems: " << matching_ids.size() <<
")";
724 const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
725 dict_like_arg, matching_ids, dict_like_arg_ti.get_notnull());
726 return codegen(in_values.get(), co);
732 const SQLOps compare_operator,
733 const std::string& pattern) {
734 std::vector<int> ret;
735 switch (compare_operator) {
756 std::runtime_error(
"unsuported operator for string comparision");
763 const std::shared_ptr<Analyzer::Expr> rhs,
764 const SQLOps compare_operator,
767 auto rhs_cast_oper = std::dynamic_pointer_cast<
const Analyzer::UOper>(rhs);
768 auto lhs_cast_oper = std::dynamic_pointer_cast<
const Analyzer::UOper>(lhs);
771 std::shared_ptr<const Analyzer::UOper> cast_oper;
772 std::shared_ptr<const Analyzer::ColumnVar> col_var;
773 auto compare_opr = compare_operator;
774 if (lhs_col_var && rhs_col_var) {
775 if (lhs_col_var->get_type_info().getStringDictKey() ==
776 rhs_col_var->get_type_info().getStringDictKey()) {
777 if (compare_operator ==
kEQ || compare_operator ==
kNE) {
785 throw std::runtime_error(
"Decoding two Dictionary encoded columns will be slow");
786 }
else if (lhs_col_var && rhs_cast_oper) {
787 cast_oper.swap(rhs_cast_oper);
788 col_var.swap(lhs_col_var);
789 }
else if (lhs_cast_oper && rhs_col_var) {
790 cast_oper.swap(lhs_cast_oper);
791 col_var.swap(rhs_col_var);
792 switch (compare_operator) {
808 if (!cast_oper || !col_var) {
813 const auto const_expr =
822 const auto col_ti = col_var->get_type_info();
823 CHECK(col_ti.is_string());
825 const auto sdp =
executor()->getStringDictionaryProxy(
826 col_ti.getStringDictKey(),
executor()->getRowSetMemoryOwner(),
true);
828 if (sdp->storageEntryCount() > 200000000) {
829 std::runtime_error(
"Cardinality for string dictionary is too high");
833 const auto& pattern_str = *const_val.stringval;
837 std::vector<int64_t> matching_ids_64(matching_ids.size());
838 std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
840 const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
841 col_var, matching_ids_64, col_ti.get_notnull());
842 return codegen(in_values.get(), co);
849 throw std::runtime_error(
"REGEXP not supported for unnested expressions");
851 char escape_char{
'\\'};
853 auto escape_char_expr =
855 CHECK(escape_char_expr);
856 CHECK(escape_char_expr->get_type_info().is_string());
857 CHECK_EQ(
size_t(1), escape_char_expr->get_constval().stringval->size());
858 escape_char = (*escape_char_expr->get_constval().stringval)[0];
862 auto fast_dict_pattern_lv =
864 if (fast_dict_pattern_lv) {
865 return fast_dict_pattern_lv;
868 CHECK(ti.is_string());
871 "Cannot do REGEXP_LIKE on this dictionary encoded column, its cardinality is too "
879 if (str_lv.size() != 3) {
887 CHECK_EQ(
size_t(3), regexp_expr_arg_lvs.size());
889 std::vector<llvm::Value*> regexp_args{
890 str_lv[1], str_lv[2], regexp_expr_arg_lvs[1], regexp_expr_arg_lvs[2]};
891 std::string fn_name(
"regexp_like");
894 fn_name +=
"_nullable";
904 const std::shared_ptr<Analyzer::Expr> pattern_arg,
906 const char escape_char,
909 const auto cast_oper = std::dynamic_pointer_cast<
Analyzer::UOper>(pattern_arg);
915 const auto dict_regexp_arg = cast_oper->get_own_operand();
916 const auto& dict_regexp_arg_ti = dict_regexp_arg->get_type_info();
917 CHECK(dict_regexp_arg_ti.is_string());
919 const auto& dict_key = dict_regexp_arg_ti.getStringDictKey();
920 const auto sdp =
executor()->getStringDictionaryProxy(
921 dict_key,
executor()->getRowSetMemoryOwner(),
true);
922 if (sdp->storageEntryCount() > 15000000) {
925 if (sdp->getDictKey().isTransientDict()) {
936 const auto string_oper =
942 CHECK(pattern_ti.is_string());
945 const auto& pattern_str = *pattern_datum.
stringval;
946 const auto matching_ids = sdp->getRegexpLike(pattern_str, escape_char);
948 std::vector<int64_t> matching_ids_64(matching_ids.size());
949 std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
950 const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
951 dict_regexp_arg, matching_ids_64, dict_regexp_arg_ti.get_notnull());
952 return codegen(in_values.get(), co);
std::pair< const char *, size_t > getStringBytes(int32_t string_id) const noexcept
llvm::Value * codegenPerRowStringOper(const Analyzer::StringOper *string_oper, const CompilationOptions &co)
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
RUNTIME_EXPORT int32_t union_translate_string_id_to_other_dict(const int32_t string_id, const int64_t source_string_dict_handle, const int64_t dest_string_dict_handle)
std::vector< int32_t > get_compared_ids(const StringDictionaryProxy *dict, const SQLOps compare_operator, const std::string &pattern)
const Expr * get_escape_expr() const
#define DEF_APPLY_NUMERIC_STRING_OPS(value_type, value_name)
__device__ StringView string_decode(int8_t *chunk_iter_, int64_t pos)
std::unique_ptr< StringDictionaryTranslationMgr > translate_dict_strings(const Analyzer::StringOper *expr, const ExecutorDeviceType device_type, Executor *executor)
void pre_translate_string_ops(const Analyzer::StringOper *string_oper, Executor *executor)
const Expr * get_escape_expr() const
llvm::IRBuilder ir_builder_
TypeR::rep timer_stop(Type clock_begin)
llvm::Value * codegenPseudoStringOper(const Analyzer::ColumnVar *, const std::vector< StringOps_Namespace::StringOpInfo > &string_op_infos, const CompilationOptions &)
llvm::Type * get_fp_type(const int width, llvm::LLVMContext &context)
const Expr * get_arg() const
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
std::string getString(int32_t string_id) const
bool requiresPerRowTranslation() const
int32_t write_string_to_proxy(const std::string &str, const int64_t string_dict_handle)
#define TRANSIENT_DICT_ID
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
DEVICE void ChunkIter_get_nth(ChunkIter *it, int n, bool uncompress, VarlenDatum *result, bool *is_end)
const Expr * get_arg() const
RUNTIME_EXPORT int32_t apply_multi_input_string_ops_and_encode(const char *str1_ptr, const int32_t str1_len, const char *str2_ptr, const int32_t str2_len, const int64_t string_ops_handle, const int64_t string_dict_handle)
size_t formatHMS(char *buf, size_t const max, int64_t const unixtime)
#define DEF_CONVERT_TO_STRING_AND_ENCODE(value_type, value_name)
std::vector< int32_t > getCompare(const std::string &pattern, const std::string &comp_operator) const
bool get_calc_encoded_length() const
llvm::LLVMContext & context_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Classes representing a parse tree.
RUNTIME_EXPORT ALWAYS_INLINE int32_t convert_to_string_and_encode_timestamp(const int64_t operand, const int32_t dimension, const int64_t string_dict_handle)
DEVICE auto copy(ARGS &&...args)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
RUNTIME_EXPORT ALWAYS_INLINE int32_t convert_to_string_and_encode_date(const int64_t operand, const int64_t string_dict_handle)
bool get_is_simple() const
std::string_view stringView() const
llvm::Value * codegenDictStrCmp(const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const SQLOps, const CompilationOptions &co)
llvm::Value * codegenDictRegexp(const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const char escape_char, const CompilationOptions &)
double power10inv(unsigned const x)
std::string toString(const Executor::ExtModuleKinds &kind)
int32_t getOrAddTransient(const std::string &)
const SQLTypeInfo & get_type_info() const
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
#define DEF_APPLY_MULTI_INPUT_NUMERIC_STRING_OPS(value_type, value_name)
llvm::Constant * inlineNull(const SQLTypeInfo &)
ExecutorDeviceType device_type
std::vector< StringOps_Namespace::StringOpInfo > getStringOpInfos(const Analyzer::StringOper *expr)
size_t formatDate(char *buf, size_t const max, int64_t const unixtime)
RUNTIME_EXPORT ALWAYS_INLINE int32_t convert_to_string_and_encode_decimal(const int64_t operand, const int32_t precision, const int32_t scale, const int64_t string_dict_handle)
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
const Expr * get_pattern_expr() const
Expression class for string functions The "arg" constructor parameter must be an expression that reso...
RUNTIME_EXPORT int32_t intersect_translate_string_id_to_other_dict(const int32_t string_id, const int64_t source_string_dict_handle, const int64_t dest_string_dict_handle)
RUNTIME_EXPORT int32_t apply_string_ops_and_encode(const char *str_ptr, const int32_t str_len, const int64_t string_ops_handle, const int64_t string_dict_handle)
SqlStringOpKind get_kind() const
const Expr * get_like_expr() const
Datum get_constval() const
const Expr * get_arg() const
llvm::StructType * createStringViewStructType()
size_t formatDateTime(char *buf, size_t const max, int64_t const timestamp, int const dimension, bool use_iso_format)
std::pair< std::vector< llvm::Value * >, std::unique_ptr< CodeGenerator::NullCheckCodegen > > codegenStringFetchAndEncode(const Analyzer::StringOper *expr, const CompilationOptions &co, const size_t arg_idx, const bool codegen_nullcheck)
RUNTIME_EXPORT ALWAYS_INLINE int32_t convert_to_string_and_encode_time(const int64_t operand, const int64_t string_dict_handle)
RUNTIME_EXPORT ALWAYS_INLINE int32_t convert_to_string_and_encode_bool(const int8_t operand, const int64_t string_dict_handle)
const Expr * get_arg() const
llvm::ConstantInt * llInt(const T v) const
const StringDictionaryTranslationMgr * moveStringDictionaryTranslationMgr(std::unique_ptr< const StringDictionaryTranslationMgr > &&str_dict_translation_mgr)
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
bool is_unnest(const Analyzer::Expr *expr)
HOST DEVICE bool get_notnull() const
llvm::Value * codegen(llvm::Value *str_id_input, const SQLTypeInfo &input_ti, const bool add_nullcheck, const CompilationOptions &co) const
size_t getNonLiteralsArity() const
std::vector< std::shared_ptr< Analyzer::Expr > > getChainedStringOpExprs() const
const Expr * getArg(const size_t i) const
RUNTIME_EXPORT int32_t string_compress(const StringView string_view, const int64_t string_dict_handle)
bool get_is_ilike() const
const shared::StringDictKey & getStringDictKey() const
llvm::Value * codegenDictLike(const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const bool ilike, const bool is_simple, const char escape_char, const CompilationOptions &)
Executor * executor() const
RUNTIME_EXPORT StringView string_decompress(const int32_t string_id, const int64_t string_dict_handle)