OmniSciDB  04ee39c94c
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 669 of file ParserNode.h.

Constructor & Destructor Documentation

◆ CaseExpr()

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

Definition at line 671 of file ParserNode.h.

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

671  : else_expr(e) {
672  CHECK(w);
673  for (const auto e : *w) {
674  when_then_list.emplace_back(e);
675  }
676  delete w;
677  }
std::list< std::unique_ptr< ExprPair > > when_then_list
Definition: ParserNode.h:689
#define CHECK(condition)
Definition: Logger.h:187
std::unique_ptr< Expr > else_expr
Definition: ParserNode.h:690
+ 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 859 of file ParserNode.cpp.

References kBOOLEAN.

862  {
863  SQLTypeInfo ti;
864  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
865  expr_pair_list;
866  for (auto& p : when_then_list) {
867  auto e1 = p->get_expr1()->analyze(catalog, query, allow_tlist_ref);
868  if (e1->get_type_info().get_type() != kBOOLEAN) {
869  throw std::runtime_error("Only boolean expressions can be used after WHEN.");
870  }
871  auto e2 = p->get_expr2()->analyze(catalog, query, allow_tlist_ref);
872  expr_pair_list.emplace_back(e1, e2);
873  }
874  auto else_e = else_expr ? else_expr->analyze(catalog, query, allow_tlist_ref) : nullptr;
875  return normalize(expr_pair_list, else_e);
876 }
std::list< std::unique_ptr< ExprPair > > when_then_list
Definition: ParserNode.h:689
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:890
std::unique_ptr< Expr > else_expr
Definition: ParserNode.h:690

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

References CHECK, Analyzer::BinOper::common_numeric_type(), Analyzer::BinOper::common_string_type(), anonymous_namespace{ImportTest.cpp}::d(), Parser::anonymous_namespace{ParserNode.cpp}::expr_is_null(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_boolean(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_number(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), kNULLT, and SQLTypeInfoCore< TYPE_FACET_PACK >::set_notnull().

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

893  {
894  SQLTypeInfo ti;
895  bool has_agg = false;
896  for (auto& p : expr_pair_list) {
897  auto e1 = p.first;
898  CHECK(e1->get_type_info().is_boolean());
899  auto e2 = p.second;
900  if (ti.get_type() == kNULLT) {
901  ti = e2->get_type_info();
902  } else if (e2->get_type_info().get_type() == kNULLT) {
903  ti.set_notnull(false);
904  e2->set_type_info(ti);
905  } else if (ti != e2->get_type_info()) {
906  if (ti.is_string() && e2->get_type_info().is_string()) {
907  ti = Analyzer::BinOper::common_string_type(ti, e2->get_type_info());
908  } else if (ti.is_number() && e2->get_type_info().is_number()) {
909  ti = Analyzer::BinOper::common_numeric_type(ti, e2->get_type_info());
910  } else if (ti.is_boolean() && e2->get_type_info().is_boolean()) {
911  ti = Analyzer::BinOper::common_numeric_type(ti, e2->get_type_info());
912  } else {
913  throw std::runtime_error(
914  "expressions in THEN clause must be of the same or compatible types.");
915  }
916  }
917  if (e2->get_contains_agg()) {
918  has_agg = true;
919  }
920  }
921  auto else_e = else_e_in;
922  if (else_e) {
923  if (else_e->get_contains_agg()) {
924  has_agg = true;
925  }
926  if (expr_is_null(else_e.get())) {
927  ti.set_notnull(false);
928  else_e->set_type_info(ti);
929  } else if (ti != else_e->get_type_info()) {
930  ti.set_notnull(false);
931  if (ti.is_string() && else_e->get_type_info().is_string()) {
932  ti = Analyzer::BinOper::common_string_type(ti, else_e->get_type_info());
933  } else if (ti.is_number() && else_e->get_type_info().is_number()) {
934  ti = Analyzer::BinOper::common_numeric_type(ti, else_e->get_type_info());
935  } else if (ti.is_boolean() && else_e->get_type_info().is_boolean()) {
936  ti = Analyzer::BinOper::common_numeric_type(ti, else_e->get_type_info());
937  } else {
938  throw std::runtime_error(
939  "expressions in ELSE clause must be of the same or compatible types as those "
940  "in the THEN clauses.");
941  }
942  }
943  }
944  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
945  cast_expr_pair_list;
946  for (auto p : expr_pair_list) {
947  ti.set_notnull(false);
948  cast_expr_pair_list.emplace_back(p.first, p.second->add_cast(ti));
949  }
950  if (else_e != nullptr) {
951  else_e = else_e->add_cast(ti);
952  } else {
953  Datum d;
954  // always create an else expr so that executor doesn't need to worry about it
955  ti.set_notnull(false);
956  else_e = makeExpr<Analyzer::Constant>(ti, true, d);
957  }
958  if (ti.get_type() == kNULLT) {
959  throw std::runtime_error(
960  "Can't deduce the type for case expressions, all branches null");
961  }
962  return makeExpr<Analyzer::CaseExpr>(ti, has_agg, cast_expr_pair_list, else_e);
963 }
void d(const SQLTypes expected_type, const std::string &str)
Definition: ImportTest.cpp:268
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
void set_notnull(bool n)
Definition: sqltypes.h:420
static SQLTypeInfo common_string_type(const SQLTypeInfo &type1, const SQLTypeInfo &type2)
Definition: Analyzer.cpp:379
static SQLTypeInfo common_numeric_type(const SQLTypeInfo &type1, const SQLTypeInfo &type2)
Definition: Analyzer.cpp:419
bool expr_is_null(const Analyzer::Expr *expr)
Definition: ParserNode.cpp:880
bool is_boolean() const
Definition: sqltypes.h:457
bool is_number() const
Definition: sqltypes.h:455
#define CHECK(condition)
Definition: Logger.h:187
bool is_string() const
Definition: sqltypes.h:450
+ 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 965 of file ParserNode.cpp.

965  {
966  std::string str("CASE ");
967  for (auto& p : when_then_list) {
968  str += "WHEN " + p->get_expr1()->to_string() + " THEN " +
969  p->get_expr2()->to_string() + " ";
970  }
971  if (else_expr != nullptr) {
972  str += "ELSE " + else_expr->to_string();
973  }
974  str += " END";
975  return str;
976 }
std::list< std::unique_ptr< ExprPair > > when_then_list
Definition: ParserNode.h:689
std::unique_ptr< Expr > else_expr
Definition: ParserNode.h:690

Member Data Documentation

◆ else_expr

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

Definition at line 690 of file ParserNode.h.

◆ when_then_list

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

Definition at line 689 of file ParserNode.h.


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