OmniSciDB  04ee39c94c
Parser::LikeExpr Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::LikeExpr:
+ Collaboration diagram for Parser::LikeExpr:

Public Member Functions

 LikeExpr (bool n, bool i, Expr *a, Expr *l, Expr *e)
 
bool get_is_not () const
 
const Exprget_arg () const
 
const Exprget_like_string () const
 
const Exprget_escape_string () const
 
std::shared_ptr< Analyzer::Expranalyze (const Catalog_Namespace::Catalog &catalog, Analyzer::Query &query, TlistRefType allow_tlist_ref=TLIST_NONE) const override
 
std::string to_string () const override
 
- Public Member Functions inherited from Parser::Node
virtual ~Node ()
 

Static Public Member Functions

static std::shared_ptr< Analyzer::Exprget (std::shared_ptr< Analyzer::Expr > arg_expr, std::shared_ptr< Analyzer::Expr > like_expr, std::shared_ptr< Analyzer::Expr > escape_expr, const bool is_ilike, const bool is_not)
 

Static Private Member Functions

static void check_like_expr (const std::string &like_str, char escape_char)
 
static bool test_is_simple_expr (const std::string &like_str, char escape_char)
 
static void erase_cntl_chars (std::string &like_str, char escape_char)
 

Private Attributes

bool is_not
 
bool is_ilike
 
std::unique_ptr< Exprarg
 
std::unique_ptr< Exprlike_string
 
std::unique_ptr< Exprescape_string
 

Additional Inherited Members

- Public Types inherited from Parser::Expr
enum  TlistRefType { TLIST_NONE, TLIST_REF, TLIST_COPY }
 

Detailed Description

Definition at line 491 of file ParserNode.h.

Constructor & Destructor Documentation

◆ LikeExpr()

Parser::LikeExpr::LikeExpr ( bool  n,
bool  i,
Expr a,
Expr l,
Expr e 
)
inline

Definition at line 493 of file ParserNode.h.

494  : is_not(n), is_ilike(i), arg(a), like_string(l), escape_string(e) {}
std::unique_ptr< Expr > escape_string
Definition: ParserNode.h:515
std::unique_ptr< Expr > like_string
Definition: ParserNode.h:514
std::unique_ptr< Expr > arg
Definition: ParserNode.h:513

Member Function Documentation

◆ analyze()

std::shared_ptr< Analyzer::Expr > Parser::LikeExpr::analyze ( const Catalog_Namespace::Catalog catalog,
Analyzer::Query query,
TlistRefType  allow_tlist_ref = TLIST_NONE 
) const
overridevirtual

Implements Parser::Expr.

Definition at line 514 of file ParserNode.cpp.

517  {
518  auto arg_expr = arg->analyze(catalog, query, allow_tlist_ref);
519  auto like_expr = like_string->analyze(catalog, query, allow_tlist_ref);
520  auto escape_expr = escape_string == nullptr
521  ? nullptr
522  : escape_string->analyze(catalog, query, allow_tlist_ref);
523  return LikeExpr::get(arg_expr, like_expr, escape_expr, is_ilike, is_not);
524 }
std::unique_ptr< Expr > escape_string
Definition: ParserNode.h:515
static std::shared_ptr< Analyzer::Expr > get(std::shared_ptr< Analyzer::Expr > arg_expr, std::shared_ptr< Analyzer::Expr > like_expr, std::shared_ptr< Analyzer::Expr > escape_expr, const bool is_ilike, const bool is_not)
Definition: ParserNode.cpp:526
std::unique_ptr< Expr > like_string
Definition: ParserNode.h:514
std::unique_ptr< Expr > arg
Definition: ParserNode.h:513

◆ check_like_expr()

void Parser::LikeExpr::check_like_expr ( const std::string &  like_str,
char  escape_char 
)
staticprivate

Definition at line 468 of file ParserNode.cpp.

468  {
469  if (like_str.back() == escape_char) {
470  throw std::runtime_error("LIKE pattern must not end with escape character.");
471  }
472 }

◆ erase_cntl_chars()

void Parser::LikeExpr::erase_cntl_chars ( std::string &  like_str,
char  escape_char 
)
staticprivate

Definition at line 495 of file ParserNode.cpp.

495  {
496  char prev_char = '\0';
497  // easier to create new string of allowable chars
498  // rather than erase chars from
499  // existing string
500  std::string new_str;
501  for (char& cur_char : like_str) {
502  if (cur_char == '%' || cur_char == escape_char) {
503  if (prev_char != escape_char) {
504  prev_char = cur_char;
505  continue;
506  }
507  }
508  new_str.push_back(cur_char);
509  prev_char = cur_char;
510  }
511  like_str = new_str;
512 }

◆ get()

std::shared_ptr< Analyzer::Expr > Parser::LikeExpr::get ( std::shared_ptr< Analyzer::Expr arg_expr,
std::shared_ptr< Analyzer::Expr like_expr,
std::shared_ptr< Analyzer::Expr escape_expr,
const bool  is_ilike,
const bool  is_not 
)
static

Definition at line 526 of file ParserNode.cpp.

References anonymous_namespace{ExecuteTest.cpp}::c(), kBOOLEAN, kNOT, and run-benchmark-import::result.

Referenced by RelAlgTranslator::translateLike(), and anonymous_namespace{CalciteAdapter.cpp}::CalciteAdapter::translateLike().

530  {
531  if (!arg_expr->get_type_info().is_string()) {
532  throw std::runtime_error("expression before LIKE must be of a string type.");
533  }
534  if (!like_expr->get_type_info().is_string()) {
535  throw std::runtime_error("expression after LIKE must be of a string type.");
536  }
537  char escape_char = '\\';
538  if (escape_expr != nullptr) {
539  if (!escape_expr->get_type_info().is_string()) {
540  throw std::runtime_error("expression after ESCAPE must be of a string type.");
541  }
542  if (!escape_expr->get_type_info().is_string()) {
543  throw std::runtime_error("expression after ESCAPE must be of a string type.");
544  }
545  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(escape_expr);
546  if (c != nullptr && c->get_constval().stringval->length() > 1) {
547  throw std::runtime_error("String after ESCAPE must have a single character.");
548  }
549  escape_char = (*c->get_constval().stringval)[0];
550  }
551  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(like_expr);
552  bool is_simple = false;
553  if (c != nullptr) {
554  std::string& pattern = *c->get_constval().stringval;
555  if (is_ilike) {
556  std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
557  }
558  check_like_expr(pattern, escape_char);
559  is_simple = test_is_simple_expr(pattern, escape_char);
560  if (is_simple) {
561  erase_cntl_chars(pattern, escape_char);
562  }
563  }
564  std::shared_ptr<Analyzer::Expr> result = makeExpr<Analyzer::LikeExpr>(
565  arg_expr->decompress(), like_expr, escape_expr, is_ilike, is_simple);
566  if (is_not) {
567  result = makeExpr<Analyzer::UOper>(kBOOLEAN, kNOT, result);
568  }
569  return result;
570 }
void c(const std::string &query_string, const ExecutorDeviceType device_type)
static void erase_cntl_chars(std::string &like_str, char escape_char)
Definition: ParserNode.cpp:495
static bool test_is_simple_expr(const std::string &like_str, char escape_char)
Definition: ParserNode.cpp:474
Definition: sqldefs.h:39
static void check_like_expr(const std::string &like_str, char escape_char)
Definition: ParserNode.cpp:468
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_arg()

const Expr* Parser::LikeExpr::get_arg ( ) const
inline

Definition at line 496 of file ParserNode.h.

496 { return arg.get(); }
std::unique_ptr< Expr > arg
Definition: ParserNode.h:513

◆ get_escape_string()

const Expr* Parser::LikeExpr::get_escape_string ( ) const
inline

Definition at line 498 of file ParserNode.h.

References anonymous_namespace{UpdateMetadataTest.cpp}::query, and to_string().

498 { return escape_string.get(); }
std::unique_ptr< Expr > escape_string
Definition: ParserNode.h:515
+ Here is the call graph for this function:

◆ get_is_not()

bool Parser::LikeExpr::get_is_not ( ) const
inline

Definition at line 495 of file ParserNode.h.

495 { return is_not; }

◆ get_like_string()

const Expr* Parser::LikeExpr::get_like_string ( ) const
inline

Definition at line 497 of file ParserNode.h.

497 { return like_string.get(); }
std::unique_ptr< Expr > like_string
Definition: ParserNode.h:514

◆ test_is_simple_expr()

bool Parser::LikeExpr::test_is_simple_expr ( const std::string &  like_str,
char  escape_char 
)
staticprivate

Definition at line 474 of file ParserNode.cpp.

474  {
475  // if not bounded by '%' then not a simple string
476  if (like_str.size() < 2 || like_str[0] != '%' || like_str[like_str.size() - 1] != '%') {
477  return false;
478  }
479  // if the last '%' is escaped then not a simple string
480  if (like_str[like_str.size() - 2] == escape_char &&
481  like_str[like_str.size() - 3] != escape_char) {
482  return false;
483  }
484  for (size_t i = 1; i < like_str.size() - 1; i++) {
485  if (like_str[i] == '%' || like_str[i] == '_' || like_str[i] == '[' ||
486  like_str[i] == ']') {
487  if (like_str[i - 1] != escape_char) {
488  return false;
489  }
490  }
491  }
492  return true;
493 }

◆ to_string()

std::string Parser::LikeExpr::to_string ( ) const
overridevirtual

Implements Parser::Expr.

Definition at line 1427 of file ParserNode.cpp.

1427  {
1428  std::string str = arg->to_string();
1429  if (is_not) {
1430  str += " NOT LIKE ";
1431  } else {
1432  str += " LIKE ";
1433  }
1434  str += like_string->to_string();
1435  if (escape_string != nullptr) {
1436  str += " ESCAPE " + escape_string->to_string();
1437  }
1438  return str;
1439 }
std::unique_ptr< Expr > escape_string
Definition: ParserNode.h:515
std::unique_ptr< Expr > like_string
Definition: ParserNode.h:514
std::unique_ptr< Expr > arg
Definition: ParserNode.h:513

Member Data Documentation

◆ arg

std::unique_ptr<Expr> Parser::LikeExpr::arg
private

Definition at line 513 of file ParserNode.h.

◆ escape_string

std::unique_ptr<Expr> Parser::LikeExpr::escape_string
private

Definition at line 515 of file ParserNode.h.

◆ is_ilike

bool Parser::LikeExpr::is_ilike
private

Definition at line 512 of file ParserNode.h.

◆ is_not

bool Parser::LikeExpr::is_not
private

Definition at line 511 of file ParserNode.h.

◆ like_string

std::unique_ptr<Expr> Parser::LikeExpr::like_string
private

Definition at line 514 of file ParserNode.h.


The documentation for this class was generated from the following files: