OmniSciDB  c1a53651b2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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::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)
 

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

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 > arg_
Definition: ParserNode.h:513
std::unique_ptr< Expr > escape_string_
Definition: ParserNode.h:515
constexpr double a
Definition: Utm.h:32
std::unique_ptr< Expr > like_string_
Definition: ParserNode.h:514
constexpr double n
Definition: Utm.h:38

Member Function Documentation

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 683 of file ParserNode.cpp.

686  {
687  auto arg_expr = arg_->analyze(catalog, query, allow_tlist_ref);
688  auto like_expr = like_string_->analyze(catalog, query, allow_tlist_ref);
689  auto escape_expr = escape_string_ == nullptr
690  ? nullptr
691  : escape_string_->analyze(catalog, query, allow_tlist_ref);
692  return LikeExpr::get(arg_expr, like_expr, escape_expr, is_ilike_, is_not_);
693 }
std::unique_ptr< Expr > arg_
Definition: ParserNode.h:513
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:695
std::unique_ptr< Expr > like_string_
Definition: ParserNode.h:514
void Parser::LikeExpr::check_like_expr ( const std::string &  like_str,
char  escape_char 
)
staticprivate

Definition at line 637 of file ParserNode.cpp.

637  {
638  if (like_str.back() == escape_char) {
639  throw std::runtime_error("LIKE pattern must not end with escape character.");
640  }
641 }
void Parser::LikeExpr::erase_cntl_chars ( std::string &  like_str,
char  escape_char 
)
staticprivate

Definition at line 664 of file ParserNode.cpp.

664  {
665  char prev_char = '\0';
666  // easier to create new string of allowable chars
667  // rather than erase chars from
668  // existing string
669  std::string new_str;
670  for (char& cur_char : like_str) {
671  if (cur_char == '%' || cur_char == escape_char) {
672  if (prev_char != escape_char) {
673  prev_char = cur_char;
674  continue;
675  }
676  }
677  new_str.push_back(cur_char);
678  prev_char = cur_char;
679  }
680  like_str = new_str;
681 }
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 695 of file ParserNode.cpp.

References Analyzer::Constant::get_constval(), kBOOLEAN, kNOT, run_benchmark_import::result, Datum::stringval, and shared::transform().

Referenced by RelAlgTranslator::translateLike().

699  {
700  if (!arg_expr->get_type_info().is_string()) {
701  throw std::runtime_error("expression before LIKE must be of a string type.");
702  }
703  if (!like_expr->get_type_info().is_string()) {
704  throw std::runtime_error("expression after LIKE must be of a string type.");
705  }
706  char escape_char = '\\';
707  if (escape_expr != nullptr) {
708  if (!escape_expr->get_type_info().is_string()) {
709  throw std::runtime_error("expression after ESCAPE must be of a string type.");
710  }
711  if (!escape_expr->get_type_info().is_string()) {
712  throw std::runtime_error("expression after ESCAPE must be of a string type.");
713  }
714  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(escape_expr);
715  if (c != nullptr && c->get_constval().stringval->length() > 1) {
716  throw std::runtime_error("String after ESCAPE must have a single character.");
717  }
718  escape_char = (*c->get_constval().stringval)[0];
719  }
720  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(like_expr);
721  bool is_simple = false;
722  if (c != nullptr) {
723  std::string& pattern = *c->get_constval().stringval;
724  if (is_ilike) {
725  std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
726  }
727  check_like_expr(pattern, escape_char);
728  is_simple = test_is_simple_expr(pattern, escape_char);
729  if (is_simple) {
730  erase_cntl_chars(pattern, escape_char);
731  }
732  }
733  std::shared_ptr<Analyzer::Expr> result = makeExpr<Analyzer::LikeExpr>(
734  arg_expr->decompress(), like_expr, escape_expr, is_ilike, is_simple);
735  if (is_not) {
736  result = makeExpr<Analyzer::UOper>(kBOOLEAN, kNOT, result);
737  }
738  return result;
739 }
OUTPUT transform(INPUT const &input, FUNC const &func)
Definition: misc.h:320
static void erase_cntl_chars(std::string &like_str, char escape_char)
Definition: ParserNode.cpp:664
std::string * stringval
Definition: Datum.h:77
Datum get_constval() const
Definition: Analyzer.h:348
static bool test_is_simple_expr(const std::string &like_str, char escape_char)
Definition: ParserNode.cpp:643
Definition: sqldefs.h:38
static void check_like_expr(const std::string &like_str, char escape_char)
Definition: ParserNode.cpp:637

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 496 of file ParserNode.h.

References arg_.

496 { return arg_.get(); }
std::unique_ptr< Expr > arg_
Definition: ParserNode.h:513
const Expr* Parser::LikeExpr::get_escape_string ( ) const
inline

Definition at line 498 of file ParserNode.h.

References escape_string_.

498 { return escape_string_.get(); }
std::unique_ptr< Expr > escape_string_
Definition: ParserNode.h:515
bool Parser::LikeExpr::get_is_not ( ) const
inline

Definition at line 495 of file ParserNode.h.

References is_not_.

495 { return is_not_; }
const Expr* Parser::LikeExpr::get_like_string ( ) const
inline

Definition at line 497 of file ParserNode.h.

References like_string_.

497 { return like_string_.get(); }
std::unique_ptr< Expr > like_string_
Definition: ParserNode.h:514
bool Parser::LikeExpr::test_is_simple_expr ( const std::string &  like_str,
char  escape_char 
)
staticprivate

Definition at line 643 of file ParserNode.cpp.

643  {
644  // if not bounded by '%' then not a simple string
645  if (like_str.size() < 2 || like_str[0] != '%' || like_str[like_str.size() - 1] != '%') {
646  return false;
647  }
648  // if the last '%' is escaped then not a simple string
649  if (like_str[like_str.size() - 2] == escape_char &&
650  like_str[like_str.size() - 3] != escape_char) {
651  return false;
652  }
653  for (size_t i = 1; i < like_str.size() - 1; i++) {
654  if (like_str[i] == '%' || like_str[i] == '_' || like_str[i] == '[' ||
655  like_str[i] == ']') {
656  if (like_str[i - 1] != escape_char) {
657  return false;
658  }
659  }
660  }
661  return true;
662 }
std::string Parser::LikeExpr::to_string ( ) const
overridevirtual

Implements Parser::Expr.

Definition at line 2222 of file ParserNode.cpp.

2222  {
2223  std::string str = arg_->to_string();
2224  if (is_not_) {
2225  str += " NOT LIKE ";
2226  } else {
2227  str += " LIKE ";
2228  }
2229  str += like_string_->to_string();
2230  if (escape_string_ != nullptr) {
2231  str += " ESCAPE " + escape_string_->to_string();
2232  }
2233  return str;
2234 }
std::unique_ptr< Expr > arg_
Definition: ParserNode.h:513
std::unique_ptr< Expr > escape_string_
Definition: ParserNode.h:515
std::unique_ptr< Expr > like_string_
Definition: ParserNode.h:514

Member Data Documentation

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

Definition at line 513 of file ParserNode.h.

Referenced by get_arg().

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

Definition at line 515 of file ParserNode.h.

Referenced by get_escape_string().

bool Parser::LikeExpr::is_ilike_
private

Definition at line 512 of file ParserNode.h.

bool Parser::LikeExpr::is_not_
private

Definition at line 511 of file ParserNode.h.

Referenced by get_is_not().

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

Definition at line 514 of file ParserNode.h.

Referenced by get_like_string().


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