OmniSciDB  dfae7c3b14
Parser::CaseExpr Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::CaseExpr:
+ Collaboration diagram for Parser::CaseExpr:

Public Member Functions

 CaseExpr (std::list< ExprPair *> *w, Expr *e)
 
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::Exprnormalize (const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &, const std::shared_ptr< Analyzer::Expr >)
 

Private Attributes

std::list< std::unique_ptr< ExprPair > > when_then_list
 
std::unique_ptr< Exprelse_expr
 

Additional Inherited Members

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

Detailed Description

Definition at line 664 of file ParserNode.h.

Constructor & Destructor Documentation

◆ CaseExpr()

Parser::CaseExpr::CaseExpr ( std::list< ExprPair *> *  w,
Expr e 
)
inline

Definition at line 666 of file ParserNode.h.

References CHECK, and to_string().

666  : else_expr(e) {
667  CHECK(w);
668  for (const auto e : *w) {
669  when_then_list.emplace_back(e);
670  }
671  delete w;
672  }
std::list< std::unique_ptr< ExprPair > > when_then_list
Definition: ParserNode.h:684
#define CHECK(condition)
Definition: Logger.h:197
std::unique_ptr< Expr > else_expr
Definition: ParserNode.h:685
+ Here is the call graph for this function:

Member Function Documentation

◆ analyze()

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

Implements Parser::Expr.

Definition at line 878 of file ParserNode.cpp.

References kBOOLEAN.

881  {
882  SQLTypeInfo ti;
883  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
884  expr_pair_list;
885  for (auto& p : when_then_list) {
886  auto e1 = p->get_expr1()->analyze(catalog, query, allow_tlist_ref);
887  if (e1->get_type_info().get_type() != kBOOLEAN) {
888  throw std::runtime_error("Only boolean expressions can be used after WHEN.");
889  }
890  auto e2 = p->get_expr2()->analyze(catalog, query, allow_tlist_ref);
891  expr_pair_list.emplace_back(e1, e2);
892  }
893  auto else_e = else_expr ? else_expr->analyze(catalog, query, allow_tlist_ref) : nullptr;
894  return normalize(expr_pair_list, else_e);
895 }
std::list< std::unique_ptr< ExprPair > > when_then_list
Definition: ParserNode.h:684
static std::shared_ptr< Analyzer::Expr > normalize(const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &, const std::shared_ptr< Analyzer::Expr >)
Definition: ParserNode.cpp:920
std::unique_ptr< Expr > else_expr
Definition: ParserNode.h:685

◆ normalize()

std::shared_ptr< Analyzer::Expr > Parser::CaseExpr::normalize ( const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &  expr_pair_list,
const std::shared_ptr< Analyzer::Expr else_e_in 
)
static

Definition at line 920 of file ParserNode.cpp.

References CHECK, Analyzer::BinOper::common_numeric_type(), Analyzer::BinOper::common_string_type(), Parser::anonymous_namespace{ParserNode.cpp}::expr_is_null(), get_logical_type_info(), SQLTypeInfo::get_type(), SQLTypeInfo::is_boolean(), SQLTypeInfo::is_number(), SQLTypeInfo::is_string(), kNULLT, and SQLTypeInfo::set_notnull().

Referenced by QueryRewriter::rewriteColumnarDelete(), QueryRewriter::rewriteColumnarUpdate(), and RelAlgTranslator::translateCase().

923  {
924  SQLTypeInfo ti;
925  bool has_agg = false;
926  for (auto& p : expr_pair_list) {
927  auto e1 = p.first;
928  CHECK(e1->get_type_info().is_boolean());
929  auto e2 = p.second;
930  if (ti.get_type() == kNULLT) {
931  ti = e2->get_type_info();
932  } else if (e2->get_type_info().get_type() == kNULLT) {
933  ti.set_notnull(false);
934  e2->set_type_info(ti);
935  } else if (ti != e2->get_type_info()) {
936  if (ti.is_string() && e2->get_type_info().is_string()) {
937  ti = Analyzer::BinOper::common_string_type(ti, e2->get_type_info());
938  } else if (ti.is_number() && e2->get_type_info().is_number()) {
939  ti = Analyzer::BinOper::common_numeric_type(ti, e2->get_type_info());
940  } else if (ti.is_boolean() && e2->get_type_info().is_boolean()) {
941  ti = Analyzer::BinOper::common_numeric_type(ti, e2->get_type_info());
942  } else {
943  throw std::runtime_error(
944  "expressions in THEN clause must be of the same or compatible types.");
945  }
946  }
947  if (e2->get_contains_agg()) {
948  has_agg = true;
949  }
950  }
951  auto else_e = else_e_in;
952  if (else_e) {
953  if (else_e->get_contains_agg()) {
954  has_agg = true;
955  }
956  if (expr_is_null(else_e.get())) {
957  ti.set_notnull(false);
958  else_e->set_type_info(ti);
959  } else if (ti != else_e->get_type_info()) {
960  ti.set_notnull(false);
961  if (ti.is_string() && else_e->get_type_info().is_string()) {
962  ti = Analyzer::BinOper::common_string_type(ti, else_e->get_type_info());
963  } else if (ti.is_number() && else_e->get_type_info().is_number()) {
964  ti = Analyzer::BinOper::common_numeric_type(ti, else_e->get_type_info());
965  } else if (ti.is_boolean() && else_e->get_type_info().is_boolean()) {
966  ti = Analyzer::BinOper::common_numeric_type(ti, else_e->get_type_info());
967  } else if (get_logical_type_info(ti) !=
968  get_logical_type_info(else_e->get_type_info())) {
969  throw std::runtime_error(
970  // types differing by encoding will be resolved at decode
971 
972  "expressions in ELSE clause must be of the same or compatible types as those "
973  "in the THEN clauses.");
974  }
975  }
976  }
977  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
978  cast_expr_pair_list;
979  for (auto p : expr_pair_list) {
980  ti.set_notnull(false);
981  cast_expr_pair_list.emplace_back(p.first, p.second->add_cast(ti));
982  }
983  if (else_e != nullptr) {
984  else_e = else_e->add_cast(ti);
985  } else {
986  Datum d;
987  // always create an else expr so that executor doesn't need to worry about it
988  ti.set_notnull(false);
989  else_e = makeExpr<Analyzer::Constant>(ti, true, d);
990  }
991  if (ti.get_type() == kNULLT) {
992  throw std::runtime_error(
993  "Can't deduce the type for case expressions, all branches null");
994  }
995  return makeExpr<Analyzer::CaseExpr>(ti, has_agg, cast_expr_pair_list, else_e);
996 }
bool is_string() const
Definition: sqltypes.h:417
bool is_boolean() const
Definition: sqltypes.h:424
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:820
static SQLTypeInfo common_string_type(const SQLTypeInfo &type1, const SQLTypeInfo &type2)
Definition: Analyzer.cpp:398
static SQLTypeInfo common_numeric_type(const SQLTypeInfo &type1, const SQLTypeInfo &type2)
Definition: Analyzer.cpp:438
bool expr_is_null(const Analyzer::Expr *expr)
Definition: ParserNode.cpp:899
void set_notnull(bool n)
Definition: sqltypes.h:356
#define CHECK(condition)
Definition: Logger.h:197
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
bool is_number() const
Definition: sqltypes.h:422
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ to_string()

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

Implements Parser::Expr.

Definition at line 998 of file ParserNode.cpp.

998  {
999  std::string str("CASE ");
1000  for (auto& p : when_then_list) {
1001  str += "WHEN " + p->get_expr1()->to_string() + " THEN " +
1002  p->get_expr2()->to_string() + " ";
1003  }
1004  if (else_expr != nullptr) {
1005  str += "ELSE " + else_expr->to_string();
1006  }
1007  str += " END";
1008  return str;
1009 }
std::list< std::unique_ptr< ExprPair > > when_then_list
Definition: ParserNode.h:684
std::unique_ptr< Expr > else_expr
Definition: ParserNode.h:685

Member Data Documentation

◆ else_expr

std::unique_ptr<Expr> Parser::CaseExpr::else_expr
private

Definition at line 685 of file ParserNode.h.

◆ when_then_list

std::list<std::unique_ptr<ExprPair> > Parser::CaseExpr::when_then_list
private

Definition at line 684 of file ParserNode.h.


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