OmniSciDB  c07336695a
Parser::ExportQueryStmt Class Reference

#include <ParserNode.h>

+ Inheritance diagram for Parser::ExportQueryStmt:
+ Collaboration diagram for Parser::ExportQueryStmt:

Public Member Functions

 ExportQueryStmt (std::string *q, std::string *p, std::list< NameValueAssign *> *o)
 
void execute (const Catalog_Namespace::SessionInfo &session) override
 
const std::string get_select_stmt () const
 
- Public Member Functions inherited from Parser::DDLStmt
void setColumnDescriptor (ColumnDescriptor &cd, const ColumnDef *coldef)
 
- Public Member Functions inherited from Parser::Node
virtual ~Node ()
 

Private Attributes

std::unique_ptr< std::string > select_stmt
 
std::unique_ptr< std::string > file_path
 
std::list< std::unique_ptr< NameValueAssign > > options
 

Detailed Description

Definition at line 1644 of file ParserNode.h.

Constructor & Destructor Documentation

◆ ExportQueryStmt()

Parser::ExportQueryStmt::ExportQueryStmt ( std::string *  q,
std::string *  p,
std::list< NameValueAssign *> *  o 
)
inline

Definition at line 1646 of file ParserNode.h.

References session.

1647  : select_stmt(q), file_path(p) {
1648  if (o) {
1649  for (const auto e : *o) {
1650  options.emplace_back(e);
1651  }
1652  delete o;
1653  }
1654  }
std::unique_ptr< std::string > file_path
Definition: ParserNode.h:1660
std::list< std::unique_ptr< NameValueAssign > > options
Definition: ParserNode.h:1661
std::unique_ptr< std::string > select_stmt
Definition: ParserNode.h:1659

Member Function Documentation

◆ execute()

void Parser::ExportQueryStmt::execute ( const Catalog_Namespace::SessionInfo session)
overridevirtual

Implements Parser::DDLStmt.

Definition at line 4058 of file ParserNode.cpp.

References CHECK, CHECK_EQ, datum_to_string(), Importer_NS::CopyParams::delimiter, Importer_NS::CopyParams::escape, Catalog_Namespace::SessionInfo::get_session_id(), Parser::StringLiteral::get_stringval(), TargetMetaInfo::get_type_info(), Catalog_Namespace::SessionInfo::getCatalog(), Parser::getResultSet(), Importer_NS::HAS_HEADER, Importer_NS::CopyParams::has_header, anonymous_namespace{TypedDataAccessors.h}::is_null(), kBIGINT, kBOOLEAN, kDATE, kFLOAT, kINT, kNUMERIC, kSMALLINT, kTIME, kTIMESTAMP, kTINYINT, Importer_NS::CopyParams::line_delim, Importer_NS::NO_HEADER, NULL_BIGINT, NULL_BOOLEAN, NULL_DOUBLE, NULL_FLOAT, NULL_INT, NULL_SMALLINT, Importer_NS::CopyParams::null_str, NULL_TINYINT, Importer_NS::CopyParams::quote, Importer_NS::CopyParams::quoted, and to_string().

4058  {
4059  if (SysCatalog::instance().isAggregator()) {
4060  // allow copy to statement for stand alone leafs
4061  throw std::runtime_error("Distributed export not supported yet");
4062  }
4063  auto& catalog = session.getCatalog();
4064  Importer_NS::CopyParams copy_params;
4065  if (!options.empty()) {
4066  for (auto& p : options) {
4067  if (boost::iequals(*p->get_name(), "delimiter")) {
4068  const StringLiteral* str_literal =
4069  dynamic_cast<const StringLiteral*>(p->get_value());
4070  if (str_literal == nullptr) {
4071  throw std::runtime_error("Delimiter option must be a string.");
4072  } else if (str_literal->get_stringval()->length() != 1) {
4073  throw std::runtime_error("Delimiter must be a single character string.");
4074  }
4075  copy_params.delimiter = (*str_literal->get_stringval())[0];
4076  } else if (boost::iequals(*p->get_name(), "nulls")) {
4077  const StringLiteral* str_literal =
4078  dynamic_cast<const StringLiteral*>(p->get_value());
4079  if (str_literal == nullptr) {
4080  throw std::runtime_error("Nulls option must be a string.");
4081  }
4082  copy_params.null_str = *str_literal->get_stringval();
4083  } else if (boost::iequals(*p->get_name(), "header")) {
4084  const StringLiteral* str_literal =
4085  dynamic_cast<const StringLiteral*>(p->get_value());
4086  if (str_literal == nullptr) {
4087  throw std::runtime_error("Header option must be a boolean.");
4088  }
4089  const std::string* s = str_literal->get_stringval();
4090  if (*s == "t" || *s == "true" || *s == "T" || *s == "True") {
4092  } else if (*s == "f" || *s == "false" || *s == "F" || *s == "False") {
4094  } else {
4095  throw std::runtime_error("Invalid string for boolean " + *s);
4096  }
4097  } else if (boost::iequals(*p->get_name(), "quote")) {
4098  const StringLiteral* str_literal =
4099  dynamic_cast<const StringLiteral*>(p->get_value());
4100  if (str_literal == nullptr) {
4101  throw std::runtime_error("Quote option must be a string.");
4102  } else if (str_literal->get_stringval()->length() != 1) {
4103  throw std::runtime_error("Quote must be a single character string.");
4104  }
4105  copy_params.quote = (*str_literal->get_stringval())[0];
4106  } else if (boost::iequals(*p->get_name(), "escape")) {
4107  const StringLiteral* str_literal =
4108  dynamic_cast<const StringLiteral*>(p->get_value());
4109  if (str_literal == nullptr) {
4110  throw std::runtime_error("Escape option must be a string.");
4111  } else if (str_literal->get_stringval()->length() != 1) {
4112  throw std::runtime_error("Escape must be a single character string.");
4113  }
4114  copy_params.escape = (*str_literal->get_stringval())[0];
4115  } else if (boost::iequals(*p->get_name(), "line_delimiter")) {
4116  const StringLiteral* str_literal =
4117  dynamic_cast<const StringLiteral*>(p->get_value());
4118  if (str_literal == nullptr) {
4119  throw std::runtime_error("Line_delimiter option must be a string.");
4120  } else if (str_literal->get_stringval()->length() != 1) {
4121  throw std::runtime_error("Line_delimiter must be a single character string.");
4122  }
4123  copy_params.line_delim = (*str_literal->get_stringval())[0];
4124  } else if (boost::iequals(*p->get_name(), "quoted")) {
4125  const StringLiteral* str_literal =
4126  dynamic_cast<const StringLiteral*>(p->get_value());
4127  if (str_literal == nullptr) {
4128  throw std::runtime_error("Quoted option must be a boolean.");
4129  }
4130  const std::string* s = str_literal->get_stringval();
4131  if (*s == "t" || *s == "true" || *s == "T" || *s == "True") {
4132  copy_params.quoted = true;
4133  } else if (*s == "f" || *s == "false" || *s == "F" || *s == "False") {
4134  copy_params.quoted = false;
4135  } else {
4136  throw std::runtime_error("Invalid string for boolean " + *s);
4137  }
4138  } else if (boost::iequals(*p->get_name(), "header")) {
4139  const StringLiteral* str_literal =
4140  dynamic_cast<const StringLiteral*>(p->get_value());
4141  if (str_literal == nullptr) {
4142  throw std::runtime_error("Header option must be a boolean.");
4143  }
4144  const std::string* s = str_literal->get_stringval();
4145  if (*s == "t" || *s == "true" || *s == "T" || *s == "True") {
4147  } else if (*s == "f" || *s == "false" || *s == "F" || *s == "False") {
4149  } else {
4150  throw std::runtime_error("Invalid string for boolean " + *s);
4151  }
4152  } else {
4153  throw std::runtime_error("Invalid option for COPY: " + *p->get_name());
4154  }
4155  }
4156  }
4157  std::vector<TargetMetaInfo> targets;
4158  const auto results = getResultSet(session, *select_stmt, targets);
4159  TargetMetaInfo* td = targets.data();
4160 
4161  std::ofstream outfile;
4162  if (file_path->empty() || !boost::filesystem::path(*file_path).is_absolute()) {
4163  std::string file_name;
4164  if (file_path->empty()) {
4165  file_name = session.get_session_id() + ".txt";
4166  } else {
4167  file_name = boost::filesystem::path(*file_path).filename().string();
4168  }
4169  *file_path = catalog.getBasePath() + "/mapd_export/" + session.get_session_id() + "/";
4170  if (!boost::filesystem::exists(*file_path)) {
4171  if (!boost::filesystem::create_directories(*file_path)) {
4172  throw std::runtime_error("Directory " + *file_path + " cannot be created.");
4173  }
4174  }
4175  *file_path += file_name;
4176  }
4177  outfile.open(*file_path);
4178  if (!outfile) {
4179  throw std::runtime_error("Cannot open file: " + *file_path);
4180  }
4182  bool not_first = false;
4183  size_t i = 0;
4184  for (const auto& target : targets) {
4185  std::string col_name = target.get_resname();
4186  if (col_name.empty()) {
4187  col_name = "result_" + std::to_string(i + 1);
4188  }
4189  if (not_first) {
4190  outfile << copy_params.delimiter;
4191  } else {
4192  not_first = true;
4193  }
4194  outfile << col_name;
4195  ++i;
4196  }
4197  outfile << copy_params.line_delim;
4198  }
4199  while (true) {
4200  const auto crt_row = results->getNextRow(true, true);
4201  if (crt_row.empty()) {
4202  break;
4203  }
4204  bool not_first = false;
4205  for (size_t i = 0; i < results->colCount(); ++i) {
4206  bool is_null;
4207  const auto tv = crt_row[i];
4208  const auto scalar_tv = boost::get<ScalarTargetValue>(&tv);
4209  if (not_first) {
4210  outfile << copy_params.delimiter;
4211  } else {
4212  not_first = true;
4213  }
4214  if (copy_params.quoted) {
4215  outfile << copy_params.quote;
4216  }
4217  const auto& ti = td[i].get_type_info();
4218  if (!scalar_tv) {
4219  outfile << datum_to_string(crt_row[i], ti, " | ");
4220  if (copy_params.quoted) {
4221  outfile << copy_params.quote;
4222  }
4223  continue;
4224  }
4225  if (boost::get<int64_t>(scalar_tv)) {
4226  auto int_val = *(boost::get<int64_t>(scalar_tv));
4227  switch (ti.get_type()) {
4228  case kBOOLEAN:
4229  is_null = (int_val == NULL_BOOLEAN);
4230  break;
4231  case kTINYINT:
4232  is_null = (int_val == NULL_TINYINT);
4233  break;
4234  case kSMALLINT:
4235  is_null = (int_val == NULL_SMALLINT);
4236  break;
4237  case kINT:
4238  is_null = (int_val == NULL_INT);
4239  break;
4240  case kBIGINT:
4241  is_null = (int_val == NULL_BIGINT);
4242  break;
4243  case kTIME:
4244  case kTIMESTAMP:
4245  case kDATE:
4246  is_null = (int_val == NULL_BIGINT);
4247  break;
4248  default:
4249  is_null = false;
4250  }
4251  if (is_null) {
4252  outfile << copy_params.null_str;
4253  } else if (ti.get_type() == kTIME) {
4254  const auto t = static_cast<time_t>(int_val);
4255  std::tm tm_struct;
4256  gmtime_r(&t, &tm_struct);
4257  char buf[9];
4258  strftime(buf, 9, "%T", &tm_struct);
4259  outfile << buf;
4260  } else {
4261  outfile << int_val;
4262  }
4263  } else if (boost::get<double>(scalar_tv)) {
4264  auto real_val = *(boost::get<double>(scalar_tv));
4265  if (ti.get_type() == kFLOAT) {
4266  is_null = (real_val == NULL_FLOAT);
4267  } else {
4268  is_null = (real_val == NULL_DOUBLE);
4269  }
4270  if (is_null) {
4271  outfile << copy_params.null_str;
4272  } else if (ti.get_type() == kNUMERIC) {
4273  outfile << std::setprecision(ti.get_precision()) << real_val;
4274  } else {
4275  outfile << std::setprecision(std::numeric_limits<double>::digits10 + 1)
4276  << real_val;
4277  }
4278  } else if (boost::get<float>(scalar_tv)) {
4279  CHECK_EQ(kFLOAT, ti.get_type());
4280  auto real_val = *(boost::get<float>(scalar_tv));
4281  if (real_val == NULL_FLOAT) {
4282  outfile << copy_params.null_str;
4283  } else {
4284  outfile << std::setprecision(std::numeric_limits<float>::digits10 + 1)
4285  << real_val;
4286  }
4287  } else {
4288  auto s = boost::get<NullableString>(scalar_tv);
4289  is_null = !s || boost::get<void*>(s);
4290  if (is_null) {
4291  outfile << copy_params.null_str;
4292  } else {
4293  auto s_notnull = boost::get<std::string>(s);
4294  CHECK(s_notnull);
4295  if (!copy_params.quoted) {
4296  outfile << *s_notnull;
4297  } else {
4298  size_t q = s_notnull->find(copy_params.quote);
4299  if (q == std::string::npos) {
4300  outfile << *s_notnull;
4301  } else {
4302  std::string str(*s_notnull);
4303  while (q != std::string::npos) {
4304  str.insert(q, 1, copy_params.escape);
4305  q = str.find(copy_params.quote, q + 2);
4306  }
4307  outfile << str;
4308  }
4309  }
4310  }
4311  }
4312  if (copy_params.quoted) {
4313  outfile << copy_params.quote;
4314  }
4315  }
4316  outfile << copy_params.line_delim;
4317  }
4318  outfile.close();
4319 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
#define NULL_DOUBLE
Definition: sqltypes.h:177
std::string null_str
Definition: Importer.h:100
Definition: sqltypes.h:51
#define NULL_BIGINT
Definition: sqltypes.h:175
std::string datum_to_string(const TargetValue &tv, const SQLTypeInfo &ti, const std::string &delim)
std::string get_session_id() const
Definition: SessionInfo.h:98
std::unique_ptr< std::string > file_path
Definition: ParserNode.h:1660
std::string to_string(char const *&&v)
#define NULL_TINYINT
Definition: sqltypes.h:172
Catalog & getCatalog() const
Definition: SessionInfo.h:90
#define NULL_FLOAT
Definition: sqltypes.h:176
ImportHeaderRow has_header
Definition: Importer.h:101
#define NULL_INT
Definition: sqltypes.h:174
Definition: sqltypes.h:55
bool is_null(const T &v, const SQLTypeInfo &t)
std::list< std::unique_ptr< NameValueAssign > > options
Definition: ParserNode.h:1661
std::shared_ptr< ResultSet > getResultSet(const Catalog_Namespace::SessionInfo &session, const std::string select_stmt, std::vector< TargetMetaInfo > &targets, bool validate_only=false)
#define NULL_SMALLINT
Definition: sqltypes.h:173
#define CHECK(condition)
Definition: Logger.h:187
Definition: sqltypes.h:47
std::unique_ptr< std::string > select_stmt
Definition: ParserNode.h:1659
const SQLTypeInfo & get_type_info() const
#define NULL_BOOLEAN
Definition: sqltypes.h:171
+ Here is the call graph for this function:

◆ get_select_stmt()

const std::string Parser::ExportQueryStmt::get_select_stmt ( ) const
inline

Definition at line 1656 of file ParserNode.h.

1656 { return *select_stmt; }
std::unique_ptr< std::string > select_stmt
Definition: ParserNode.h:1659

Member Data Documentation

◆ file_path

std::unique_ptr<std::string> Parser::ExportQueryStmt::file_path
private

Definition at line 1660 of file ParserNode.h.

◆ options

std::list<std::unique_ptr<NameValueAssign> > Parser::ExportQueryStmt::options
private

Definition at line 1661 of file ParserNode.h.

◆ select_stmt

std::unique_ptr<std::string> Parser::ExportQueryStmt::select_stmt
private

Definition at line 1659 of file ParserNode.h.


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