OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StringOps.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "Logger/Logger.h"
21 #include "Shared/sqldefs.h"
22 #include "Shared/sqltypes.h"
23 #include "StringOpInfo.h"
24 
25 #include <algorithm>
26 #include <bitset>
27 #include <cctype>
28 #include <cmath>
29 #include <map>
30 #include <memory>
31 #include <optional>
32 #include <string>
33 #include <string_view>
34 #include <utility>
35 #include <vector>
36 
37 namespace StringOps_Namespace {
38 
39 struct NullableStrType {
40  NullableStrType(const std::string& str) : str(str), is_null(str.empty()) {}
41  NullableStrType(const std::string_view sv) : str(sv), is_null(sv.empty()) {}
42  NullableStrType() : is_null(true) {}
43 
44  std::pair<std::string, bool> toPair() const { return {str, is_null}; }
45 
46  std::string str;
47  bool is_null;
48 };
49 
50 struct StringOp {
51  public:
52  StringOp(const SqlStringOpKind op_kind,
53  const std::optional<std::string>& var_str_optional_literal)
54  : op_kind_(op_kind)
55  , return_ti_(SQLTypeInfo(kTEXT, false, kENCODING_DICT))
56  , has_var_str_literal_(var_str_optional_literal.has_value())
57  , var_str_literal_(!var_str_optional_literal.has_value()
58  ? NullableStrType()
59  : NullableStrType(var_str_optional_literal.value())) {}
60 
61  StringOp(const SqlStringOpKind op_kind,
62  const SQLTypeInfo& return_ti,
63  const std::optional<std::string>& var_str_optional_literal)
64  : op_kind_(op_kind)
65  , return_ti_(return_ti)
66  , has_var_str_literal_(var_str_optional_literal.has_value())
67  , var_str_literal_(!var_str_optional_literal.has_value()
68  ? NullableStrType()
69  : NullableStrType(var_str_optional_literal.value())) {}
70 
71  virtual ~StringOp() = default;
72 
73  virtual NullableStrType operator()(std::string const&) const = 0;
74 
75  virtual NullableStrType operator()(const std::string& str1,
76  const std::string& str2) const {
77  UNREACHABLE() << "operator(str1, str2) not allowed for this method";
78  // Make compiler happy
79  return NullableStrType();
80  }
81 
82  virtual NullableStrType operator()() const {
83  if (var_str_literal_.is_null) {
84  return var_str_literal_;
85  }
86  CHECK(hasVarStringLiteral());
87  return operator()(var_str_literal_.str);
88  }
89 
90  virtual Datum numericEval(const std::string_view str) const {
91  UNREACHABLE() << "numericEval not allowed for this method";
92  // Make compiler happy
93  return NullDatum(SQLTypeInfo());
94  }
95 
96  virtual Datum numericEval(const std::string_view str1,
97  const std::string_view str2) const {
98  UNREACHABLE() << "numericEval not allowed for this method";
99  // Make compiler happy
100  return NullDatum(SQLTypeInfo());
101  }
102 
103  virtual Datum numericEval() const {
104  if (var_str_literal_.is_null) {
105  return NullDatum(return_ti_);
106  }
107  CHECK(hasVarStringLiteral());
108  return numericEval(var_str_literal_.str);
109  }
110 
111  virtual const SQLTypeInfo& getReturnType() const { return return_ti_; }
112 
113  const std::string& getVarStringLiteral() const {
114  CHECK(hasVarStringLiteral());
115  return var_str_literal_.str;
116  }
117 
118  bool hasVarStringLiteral() const { return has_var_str_literal_; }
119 
120  protected:
121  static boost::regex generateRegex(const std::string& op_name,
122  const std::string& regex_pattern,
123  const std::string& regex_params,
124  const bool supports_sub_matches);
125 
126  const SqlStringOpKind op_kind_;
127  const SQLTypeInfo return_ti_;
128  const bool has_var_str_literal_{false};
129  const NullableStrType var_str_literal_;
130 };
131 
132 struct TryStringCast : public StringOp {
133  public:
134  TryStringCast(const SQLTypeInfo& return_ti,
135  const std::optional<std::string>& var_str_optional_literal)
136  : StringOp(SqlStringOpKind::TRY_STRING_CAST, return_ti, var_str_optional_literal) {}
137 
138  NullableStrType operator()(const std::string& str) const override;
139  Datum numericEval(const std::string_view str) const override;
140 };
141 
142 struct Position : public StringOp {
143  public:
144  Position(const std::optional<std::string>& var_str_optional_literal,
145  const std::string& search_str)
146  : StringOp(SqlStringOpKind::POSITION,
148  var_str_optional_literal)
149  , search_str_(search_str)
150  , start_(0) {}
151 
152  Position(const std::optional<std::string>& var_str_optional_literal,
153  const std::string& search_str,
154  const int64_t start)
155  : StringOp(SqlStringOpKind::POSITION,
157  var_str_optional_literal)
158  , search_str_(search_str)
159  , start_(start > 0 ? start - 1 : start) {}
160 
161  NullableStrType operator()(const std::string& str) const override;
162  Datum numericEval(const std::string_view str) const override;
163 
164  private:
165  const std::string search_str_;
166  const int64_t start_;
167 };
168 
169 struct JarowinklerSimilarity : public StringOp {
170  JarowinklerSimilarity(const std::optional<std::string>& var_str_optional_literal,
171  const std::string& str_literal)
174  var_str_optional_literal)
175  , str_literal_(str_literal) {}
176 
177  JarowinklerSimilarity(const std::optional<std::string>& var_str_optional_literal)
178  : StringOp(SqlStringOpKind::JAROWINKLER_SIMILARITY, var_str_optional_literal) {}
179 
180  NullableStrType operator()(const std::string& str) const override;
181 
182  Datum numericEval(const std::string_view str) const override;
183  Datum numericEval(const std::string_view str1,
184  const std::string_view str2) const override;
185 
186  const std::string str_literal_;
187 };
188 
189 struct LevenshteinDistance : public StringOp {
190  LevenshteinDistance(const std::optional<std::string>& var_str_optional_literal,
191  const std::string& str_literal)
194  var_str_optional_literal)
195  , str_literal_(str_literal) {}
196 
197  LevenshteinDistance(const std::optional<std::string>& var_str_optional_literal)
198  : StringOp(SqlStringOpKind::LEVENSHTEIN_DISTANCE, var_str_optional_literal) {}
199 
200  NullableStrType operator()(const std::string& str) const override;
201 
202  Datum numericEval(const std::string_view str) const override;
203  Datum numericEval(const std::string_view str1,
204  const std::string_view str2) const override;
205 
206  const std::string str_literal_;
207 };
208 
209 struct Hash : public StringOp {
210  public:
211  Hash(const std::optional<std::string>& var_str_optional_literal)
212  : StringOp(SqlStringOpKind::HASH, SQLTypeInfo(kBIGINT), var_str_optional_literal) {}
213 
214  NullableStrType operator()(const std::string& str) const override;
215  Datum numericEval(const std::string_view str) const override;
216 };
217 
218 struct Lower : public StringOp {
219  Lower(const std::optional<std::string>& var_str_optional_literal)
220  : StringOp(SqlStringOpKind::LOWER, var_str_optional_literal) {}
221 
222  NullableStrType operator()(const std::string& str) const override;
223 };
224 
225 struct Upper : public StringOp {
226  Upper(const std::optional<std::string>& var_str_optional_literal)
227  : StringOp(SqlStringOpKind::UPPER, var_str_optional_literal) {}
228  NullableStrType operator()(const std::string& str) const override;
229 };
230 
231 inline std::bitset<256> build_char_bitmap(const std::string& chars_to_set) {
232  std::bitset<256> char_bitmap;
233  for (const auto& str_char : chars_to_set) {
234  char_bitmap.set(str_char);
235  }
236  return char_bitmap;
237 }
238 
239 struct InitCap : public StringOp {
240  InitCap(const std::optional<std::string>& var_str_optional_literal)
241  : StringOp(SqlStringOpKind::INITCAP, var_str_optional_literal)
242  , delimiter_bitmap_(build_char_bitmap(InitCap::delimiter_chars)) {}
243 
244  NullableStrType operator()(const std::string& str) const override;
245 
246  private:
247  static constexpr char const* delimiter_chars = R"(!?@"^#$&~_,.:;+-*%/|\[](){}<>)";
248  const std::bitset<256> delimiter_bitmap_;
249 };
250 
251 struct Reverse : public StringOp {
252  Reverse(const std::optional<std::string>& var_str_optional_literal)
253  : StringOp(SqlStringOpKind::REVERSE, var_str_optional_literal) {}
254 
255  NullableStrType operator()(const std::string& str) const override;
256 };
257 
258 struct Repeat : public StringOp {
259  public:
260  Repeat(const std::optional<std::string>& var_str_optional_literal, const int64_t n)
261  : StringOp(SqlStringOpKind::REPEAT, var_str_optional_literal)
262  , n_(n >= 0 ? n : 0UL) {
263  if (n < 0) {
264  throw std::runtime_error("Number of repeats must be >= 0");
265  }
266  }
267 
268  NullableStrType operator()(const std::string& str) const override;
269 
270  private:
271  const size_t n_;
272 };
273 
274 struct Concat : public StringOp {
275  Concat(const std::optional<std::string>& var_str_optional_literal,
276  const std::string& str_literal,
277  const bool reverse_order)
278  : StringOp(reverse_order ? SqlStringOpKind::RCONCAT : SqlStringOpKind::CONCAT,
279  var_str_optional_literal)
280  , str_literal_(str_literal)
281  , reverse_order_(reverse_order) {}
282 
283  Concat(const std::optional<std::string>& var_str_optional_literal)
284  : StringOp(SqlStringOpKind::CONCAT, var_str_optional_literal)
285  , reverse_order_(false) {}
286 
287  NullableStrType operator()(const std::string& str) const override;
288 
289  NullableStrType operator()(const std::string& str1,
290  const std::string& str2) const override;
291 
292  const std::string str_literal_;
293  const bool reverse_order_;
294 };
295 
296 struct Pad : public StringOp {
297  public:
298  enum class PadMode { LEFT, RIGHT };
299 
300  Pad(const std::optional<std::string>& var_str_optional_literal,
301  const SqlStringOpKind op_kind,
302  const int64_t padded_length,
303  const std::string& padding_string)
304  : StringOp(op_kind, var_str_optional_literal)
305  , pad_mode_(Pad::op_kind_to_pad_mode(op_kind))
306  , padded_length_(static_cast<size_t>(padded_length))
307  , padding_string_(padding_string.empty() ? " " : padding_string)
308  , padding_string_length_(padding_string.size())
309  , padding_char_(padding_string.empty() ? ' ' : padding_string[0]) {}
310 
311  NullableStrType operator()(const std::string& str) const override;
312 
313  private:
314  std::string lpad(const std::string& str) const;
315 
316  std::string rpad(const std::string& str) const;
317 
318  static PadMode op_kind_to_pad_mode(const SqlStringOpKind op_kind);
319 
320  const PadMode pad_mode_;
321  const size_t padded_length_;
322  const std::string padding_string_;
323  const size_t padding_string_length_;
324  const char padding_char_;
325 };
326 
327 struct Trim : public StringOp {
328  public:
329  enum class TrimMode { LEFT, RIGHT, BOTH };
330 
331  Trim(const std::optional<std::string>& var_str_optional_literal,
332  const SqlStringOpKind op_kind,
333  const std::string& trim_chars)
334  : StringOp(op_kind, var_str_optional_literal)
335  , trim_mode_(Trim::op_kind_to_trim_mode(op_kind))
336  , trim_char_bitmap_(build_char_bitmap(trim_chars.empty() ? " " : trim_chars)) {}
337 
338  NullableStrType operator()(const std::string& str) const override;
339 
340  private:
341  static TrimMode op_kind_to_trim_mode(const SqlStringOpKind op_kind);
342 
343  const TrimMode trim_mode_;
344  const std::bitset<256> trim_char_bitmap_;
345 };
346 
347 struct Substring : public StringOp {
348  // First constructor is for CALCITE SUBSTRING(str FROM start_pos),
349  // which returns the substring of str from start_pos
350  // until the end of the string
351  // Note start_pos is 1-indexed, unless input is 0
352 
353  Substring(const std::optional<std::string>& var_str_optional_literal,
354  const int64_t start)
355  : StringOp(SqlStringOpKind::SUBSTRING, var_str_optional_literal)
356  , start_(start > 0 ? start - 1 : start)
357  , length_(std::string::npos) {}
358 
359  // Second constructor is for CALCITE
360  // SUBSTRING(str FROM start_pos FOR length),
361  // which copies from start_pos for length characters
362  // Note start_pos is 1-indexed, unless input is 0
363  Substring(const std::optional<std::string>& var_str_optional_literal,
364  const int64_t start,
365  const int64_t length)
366  : StringOp(SqlStringOpKind::SUBSTRING, var_str_optional_literal)
367  , start_(start > 0 ? start - 1 : start)
368  , length_(static_cast<size_t>(length >= 0 ? length : 0)) {}
369 
370  NullableStrType operator()(const std::string& str) const override;
371 
372  // Make string_view version?
373  const int64_t start_;
374  const size_t length_;
375 };
376 
377 struct Overlay : public StringOp {
378  Overlay(const std::optional<std::string>& var_str_optional_literal,
379  const std::string& insert_str,
380  const int64_t start)
381  : StringOp(SqlStringOpKind::OVERLAY, var_str_optional_literal)
382  , insert_str_(insert_str)
383  , start_(start > 0 ? start - 1 : start)
384  , replacement_length_(insert_str_.size()) {}
385 
386  Overlay(const std::optional<std::string>& var_str_optional_literal,
387  const std::string& insert_str,
388  const int64_t start,
389  const int64_t replacement_length)
390  : StringOp(SqlStringOpKind::OVERLAY, var_str_optional_literal)
391  , insert_str_(insert_str)
392  , start_(start > 0 ? start - 1 : start)
393  , replacement_length_(
394  static_cast<size_t>(replacement_length >= 0 ? replacement_length : 0)) {}
395 
396  NullableStrType operator()(const std::string& base_str) const override;
397 
398  // Make string_view version?
399  const std::string insert_str_;
400  const int64_t start_;
401  const size_t replacement_length_;
402 };
403 
404 struct Replace : public StringOp {
405  Replace(const std::optional<std::string>& var_str_optional_literal,
406  const std::string& pattern_str,
407  const std::string& replacement_str)
408  : StringOp(SqlStringOpKind::REPLACE, var_str_optional_literal)
409  , pattern_str_(pattern_str)
410  , replacement_str_(replacement_str)
411  , pattern_str_len_(pattern_str.size())
412  , replacement_str_len_(replacement_str.size()) {}
413 
414  NullableStrType operator()(const std::string& str) const override;
415 
416  const std::string pattern_str_;
417  const std::string replacement_str_;
418  const size_t pattern_str_len_;
419  const size_t replacement_str_len_;
420 };
421 
422 struct SplitPart : public StringOp {
423  SplitPart(const std::optional<std::string>& var_str_optional_literal,
424  const std::string& delimiter,
425  const int64_t split_part)
426  : StringOp(SqlStringOpKind::SPLIT_PART, var_str_optional_literal)
427  , delimiter_(delimiter)
428  , split_part_(split_part == 0 ? 1UL : std::abs(split_part))
429  , delimiter_length_(delimiter.size())
430  , reverse_(split_part < 0) {}
431 
432  NullableStrType operator()(const std::string& str) const override;
433 
434  // Make string_view version?
435 
436  const std::string delimiter_;
437  const size_t split_part_;
438  const size_t delimiter_length_;
439  const bool reverse_;
440 };
441 
442 struct RegexpSubstr : public StringOp {
443  public:
444  RegexpSubstr(const std::optional<std::string>& var_str_optional_literal,
445  const std::string& regex_pattern,
446  const int64_t start_pos,
447  const int64_t occurrence,
448  const std::string& regex_params,
449  const int64_t sub_match_group_idx)
450  : StringOp(SqlStringOpKind::REGEXP_SUBSTR, var_str_optional_literal)
451  , regex_pattern_str_(regex_pattern)
452  , regex_pattern_(
453  StringOp::generateRegex("REGEXP_SUBSTR", regex_pattern, regex_params, true))
454  , start_pos_(start_pos > 0 ? start_pos - 1 : start_pos)
455  , occurrence_(occurrence > 0 ? occurrence - 1 : occurrence)
456  , sub_match_info_(set_sub_match_info(regex_params, sub_match_group_idx)) {}
457 
458  NullableStrType operator()(const std::string& str) const override;
459 
460  private:
461  static std::string get_sub_match(const boost::smatch& match,
462  const std::pair<bool, int64_t> sub_match_info);
463 
464  static std::pair<bool, int64_t> set_sub_match_info(const std::string& regex_pattern,
465  const int64_t sub_match_group_idx);
466 
467  const std::string regex_pattern_str_;
468  const boost::regex regex_pattern_;
469  const int64_t start_pos_;
470  const int64_t occurrence_;
471  const std::pair<bool, int64_t> sub_match_info_;
472 };
473 
474 struct RegexpReplace : public StringOp {
475  public:
476  RegexpReplace(const std::optional<std::string>& var_str_optional_literal,
477  const std::string& regex_pattern,
478  const std::string& replacement,
479  const int64_t start_pos,
480  const int64_t occurrence,
481  const std::string& regex_params)
482  : StringOp(SqlStringOpKind::REGEXP_REPLACE, var_str_optional_literal)
483  , regex_pattern_str_(regex_pattern)
484  , regex_pattern_(
485  StringOp::generateRegex("REGEXP_REPLACE", regex_pattern, regex_params, false))
486  , replacement_(replacement)
487  , start_pos_(start_pos > 0 ? start_pos - 1 : start_pos)
488  , occurrence_(occurrence) {}
489 
490  NullableStrType operator()(const std::string& str) const override;
491 
492  private:
493  static std::pair<size_t, size_t> get_nth_regex_match(const std::string& str,
494  const size_t start_pos,
495  const boost::regex& regex_pattern,
496  const int64_t occurrence);
497 
498  const std::string regex_pattern_str_;
499  const boost::regex regex_pattern_;
500  const std::string replacement_;
501  const int64_t start_pos_;
502  const int64_t occurrence_;
503 };
504 
505 struct RegexpCount : public StringOp {
506  public:
507  RegexpCount(const std::optional<std::string>& var_str_optional_literal,
508  const std::string& regex_pattern,
509  const int64_t start_pos,
510  const std::string& regex_params)
511  : StringOp(SqlStringOpKind::REGEXP_COUNT,
513  var_str_optional_literal)
514  , regex_pattern_str_(regex_pattern)
515  , regex_pattern_(
516  StringOp::generateRegex("REGEXP_COUNT", regex_pattern, regex_params, true))
517  , start_pos_(start_pos > 0 ? start_pos - 1 : start_pos) {}
518 
519  NullableStrType operator()(const std::string& str) const override;
520  Datum numericEval(const std::string_view str) const override;
521 
522  private:
523  const std::string regex_pattern_str_;
524  const boost::regex regex_pattern_;
525  const int64_t start_pos_;
526 };
527 
528 // We currently do not allow strict mode JSON parsing per the SQL standard, as
529 // 1) We can't throw run-time errors in the case that the string operator
530 // is evaluated in an actual kernel, which is the case for none-encoded text
531 // inputs, and would need to capture the parsing and key errors and set
532 // kernel error flags accordingly. Currently throwing an error in even a CPU
533 // kernel will crash the server as it's not caught (by design, as executor kernels
534 // use error codes so that GPU and CPU code can throw errors).
535 // 2) When JSON_VALUE (or other not-yet-implemented JSON operators) is run over
536 // a string dictionary, if the column shares a dictionary such that the dictionary
537 // contains entries not in the column, we can throw errors for fields not in the
538 // actual column, as we compute JSON_VALUE for all values in the dictionary
539 // pre-kernel launch to build the string dictionary translation map. Since the
540 // offending values may not actually be in the column (when it references a
541 // shared dict), there is not even a way for the user to filter out or
542 // case-guard the offending values
543 // Todo(todd): Implement proper error infra for StringOps, both for the
544 // none-encoded and dictionary encoded paths
545 
546 struct JsonValue : public StringOp {
547  public:
548  JsonValue(const std::optional<std::string>& var_str_optional_literal,
549  const std::string& json_path)
550  : StringOp(SqlStringOpKind::JSON_VALUE, var_str_optional_literal)
551  , json_parse_mode_(parse_json_parse_mode(json_path))
552  , json_keys_(parse_json_path(json_path)) {}
553 
554  NullableStrType operator()(const std::string& str) const override;
555 
556  private:
557  enum class JsonKeyKind { JSON_OBJECT, JSON_ARRAY };
558  enum class JsonParseMode { PARSE_MODE_LAX, PARSE_MODE_STRICT };
559 
560  struct JsonKey {
561  JsonKeyKind key_kind;
562  std::string object_key;
563  // Todo (todd): Support array ranges ala SQL Server
564  size_t array_key;
565 
566  JsonKey(const std::string& object_key)
567  : key_kind(JsonKeyKind::JSON_OBJECT), object_key(object_key) {}
568  JsonKey(const size_t array_key)
569  : key_kind(JsonKeyKind::JSON_ARRAY), array_key(array_key) {}
570  };
571 
572  static JsonParseMode parse_json_parse_mode(std::string_view json_path);
573  static std::vector<JsonKey> parse_json_path(const std::string& json_path);
574  inline NullableStrType handle_parse_error(const std::string& json_str) const {
575  if (json_parse_mode_ == JsonParseMode::PARSE_MODE_LAX) {
576  return NullableStrType();
577  } else {
578  throw std::runtime_error("Could not parse: " + json_str + ".");
579  }
580  }
581 
582  inline NullableStrType handle_key_error(const std::string& json_str) const {
583  if (json_parse_mode_ == JsonParseMode::PARSE_MODE_LAX) {
584  return NullableStrType();
585  } else {
586  throw std::runtime_error("Key not found or did not contain value in: " + json_str +
587  ".");
588  }
589  }
590  static constexpr bool allow_strict_json_parsing{false};
591  const JsonParseMode json_parse_mode_; // If PARSE_MODE_LAX return null and don't throw
592  // error on parsing error
593  const std::vector<JsonKey> json_keys_;
594 };
595 
596 struct Base64Encode : public StringOp {
597  Base64Encode(const std::optional<std::string>& var_str_optional_literal)
598  : StringOp(SqlStringOpKind::BASE64_ENCODE, var_str_optional_literal) {}
599 
600  NullableStrType operator()(const std::string& str) const override;
601 };
602 
603 struct Base64Decode : public StringOp {
604  Base64Decode(const std::optional<std::string>& var_str_optional_literal)
605  : StringOp(SqlStringOpKind::BASE64_DECODE, var_str_optional_literal) {}
606 
607  NullableStrType operator()(const std::string& str) const override;
608 };
609 
610 struct UrlEncode : public StringOp {
611  UrlEncode(const std::optional<std::string>& var_str_optional_literal)
612  : StringOp(SqlStringOpKind::URL_ENCODE, var_str_optional_literal) {}
613 
614  NullableStrType operator()(const std::string& str) const override;
615 };
616 
617 struct UrlDecode : public StringOp {
618  UrlDecode(const std::optional<std::string>& var_str_optional_literal)
619  : StringOp(SqlStringOpKind::URL_DECODE, var_str_optional_literal) {}
620 
621  NullableStrType operator()(const std::string& str) const override;
622 };
623 
624 struct NullOp : public StringOp {
625  NullOp(const SQLTypeInfo& return_ti,
626  const std::optional<std::string>& var_str_optional_literal,
627  const SqlStringOpKind op_kind)
628  : StringOp(SqlStringOpKind::INVALID, return_ti, var_str_optional_literal)
629  , op_kind_(op_kind) {}
630 
631  NullableStrType operator()(const std::string& str) const override {
632  return NullableStrType(); // null string
633  }
634 
635  const SqlStringOpKind op_kind_;
636 };
637 
638 std::unique_ptr<const StringOp> gen_string_op(const StringOpInfo& string_op_info);
639 
640 std::pair<std::string, bool /* is null */> apply_string_op_to_literals(
641  const StringOpInfo& string_op_info);
642 
643 Datum apply_numeric_op_to_literals(const StringOpInfo& string_op_info);
644 
645 class StringOps {
646  public:
647  StringOps() : string_ops_(genStringOpsFromOpInfos({})), num_ops_(0UL) {}
648 
649  StringOps(const std::vector<StringOpInfo>& string_op_infos)
650  : string_ops_(genStringOpsFromOpInfos(string_op_infos))
651  , num_ops_(string_op_infos.size()) {}
652 
653  std::string operator()(const std::string& str) const;
654 
655  std::string multi_input_eval(const std::string_view str1,
656  const std::string_view str2) const;
657 
658  std::string_view operator()(const std::string_view sv, std::string& sv_storage) const;
659 
660  Datum numericEval(const std::string_view str) const;
661  Datum numericEval(const std::string_view str1, const std::string_view str2) const;
662 
663  size_t size() const { return num_ops_; }
664 
665  private:
666  std::vector<std::unique_ptr<const StringOp>> genStringOpsFromOpInfos(
667  const std::vector<StringOpInfo>& string_op_infos) const;
668 
669  const std::vector<std::unique_ptr<const StringOp>> string_ops_;
670  const size_t num_ops_;
671 };
672 
673 } // namespace StringOps_Namespace
Datum apply_numeric_op_to_literals(const StringOpInfo &string_op_info)
Definition: StringOps.cpp:1283
const std::string json_str(const rapidjson::Value &obj) noexcept
Definition: JsonAccessors.h:46
#define UNREACHABLE()
Definition: Logger.h:338
SqlStringOpKind
Definition: sqldefs.h:92
Constants for Builtin SQL Types supported by HEAVY.AI.
CONSTEXPR DEVICE bool is_null(const T &value)
std::pair< std::string, bool > apply_string_op_to_literals(const StringOpInfo &string_op_info)
Definition: StringOps.cpp:1272
bool g_enable_smem_group_by true
Datum NullDatum(const SQLTypeInfo &ti)
Definition: Datum.cpp:288
Definition: sqltypes.h:79
bool g_enable_watchdog false
Definition: Execute.cpp:80
#define CHECK(condition)
Definition: Logger.h:291
Common Enum definitions for SQL processing.
constexpr double n
Definition: Utm.h:38
Definition: Datum.h:71
std::unique_ptr< const StringOp > gen_string_op(const StringOpInfo &string_op_info)
Definition: StringOps.cpp:1039