OmniSciDB  04ee39c94c
anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator Class Reference
+ Collaboration diagram for anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator:

Public Member Functions

 SQLiteComparator ()
 
void query (const std::string &query_string)
 
void compare (const std::string &query_string, const ExecutorDeviceType device_type)
 
void compare_arrow_output (const std::string &query_string, const std::string &sqlite_query_string, const ExecutorDeviceType device_type)
 
void compare (const std::string &query_string, const std::string &sqlite_query_string, const ExecutorDeviceType device_type)
 
void compare_timstamp_approx (const std::string &query_string, const ExecutorDeviceType device_type)
 

Private Member Functions

template<class MapDResults >
void compare_impl (const MapDResults *mapd_results, const std::string &sqlite_query_string, const ExecutorDeviceType device_type, const bool timestamp_approx, const bool is_arrow=false)
 

Static Private Member Functions

static void checkTypeConsistency (const int ref_col_type, const SQLTypeInfo &mapd_ti)
 

Private Attributes

SqliteConnector connector_
 

Detailed Description

Definition at line 193 of file ExecuteTest.cpp.

Constructor & Destructor Documentation

◆ SQLiteComparator()

anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::SQLiteComparator ( )
inline

Definition at line 195 of file ExecuteTest.cpp.

195 : connector_("sqliteTestDB", "") {}

Member Function Documentation

◆ checkTypeConsistency()

static void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::checkTypeConsistency ( const int  ref_col_type,
const SQLTypeInfo mapd_ti 
)
inlinestaticprivate

Definition at line 423 of file ExecuteTest.cpp.

References CHECK, CHECK_EQ, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_fp(), and SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer().

423  {
424  if (ref_col_type == SQLITE_NULL) {
425  // TODO(alex): re-enable the check that mapd_ti is nullable,
426  // got invalidated because of outer joins
427  return;
428  }
429  if (mapd_ti.is_integer()) {
430  CHECK_EQ(SQLITE_INTEGER, ref_col_type);
431  } else if (mapd_ti.is_fp() || mapd_ti.is_decimal()) {
432  CHECK(ref_col_type == SQLITE_FLOAT || ref_col_type == SQLITE_INTEGER);
433  } else {
434  CHECK_EQ(SQLITE_TEXT, ref_col_type);
435  }
436  }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
bool is_fp() const
Definition: sqltypes.h:454
bool is_integer() const
Definition: sqltypes.h:452
bool is_decimal() const
Definition: sqltypes.h:453
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:

◆ compare() [1/2]

void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::compare ( const std::string &  query_string,
const ExecutorDeviceType  device_type 
)
inline

Definition at line 199 of file ExecuteTest.cpp.

References run_multiple_agg().

Referenced by anonymous_namespace{ExecuteTest.cpp}::c().

199  {
200  const auto mapd_results = run_multiple_agg(query_string, device_type);
201  compare_impl(mapd_results.get(), query_string, device_type, false);
202  }
void compare_impl(const MapDResults *mapd_results, const std::string &sqlite_query_string, const ExecutorDeviceType device_type, const bool timestamp_approx, const bool is_arrow=false)
std::shared_ptr< ResultSet > run_multiple_agg(const string &query_str, const ExecutorDeviceType device_type, const bool allow_loop_joins)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compare() [2/2]

void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::compare ( const std::string &  query_string,
const std::string &  sqlite_query_string,
const ExecutorDeviceType  device_type 
)
inline

Definition at line 213 of file ExecuteTest.cpp.

References run_multiple_agg().

215  {
216  const auto mapd_results = run_multiple_agg(query_string, device_type);
217  compare_impl(mapd_results.get(), sqlite_query_string, device_type, false);
218  }
void compare_impl(const MapDResults *mapd_results, const std::string &sqlite_query_string, const ExecutorDeviceType device_type, const bool timestamp_approx, const bool is_arrow=false)
std::shared_ptr< ResultSet > run_multiple_agg(const string &query_str, const ExecutorDeviceType device_type, const bool allow_loop_joins)
+ Here is the call graph for this function:

◆ compare_arrow_output()

void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::compare_arrow_output ( const std::string &  query_string,
const std::string &  sqlite_query_string,
const ExecutorDeviceType  device_type 
)
inline

Definition at line 204 of file ExecuteTest.cpp.

References anonymous_namespace{ExecuteTest.cpp}::g_hoist_literals, QueryRunner::QueryRunner::get(), result_set_arrow_loopback(), and QueryRunner::QueryRunner::runSQL().

Referenced by anonymous_namespace{ExecuteTest.cpp}::c_arrow().

206  {
207  const auto results =
208  QR::get()->runSQL(query_string, device_type, g_hoist_literals, true);
209  const auto arrow_mapd_results = result_set_arrow_loopback(nullptr, results);
210  compare_impl(arrow_mapd_results.get(), sqlite_query_string, device_type, false, true);
211  }
virtual std::shared_ptr< ResultSet > runSQL(const std::string &query_str, const ExecutorDeviceType device_type, const bool hoist_literals=true, const bool allow_loop_joins=true)
void compare_impl(const MapDResults *mapd_results, const std::string &sqlite_query_string, const ExecutorDeviceType device_type, const bool timestamp_approx, const bool is_arrow=false)
static QueryRunner * get()
Definition: QueryRunner.h:115
std::unique_ptr< ArrowResultSet > result_set_arrow_loopback(const ExecutionResult &results)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compare_impl()

template<class MapDResults >
void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::compare_impl ( const MapDResults *  mapd_results,
const std::string &  sqlite_query_string,
const ExecutorDeviceType  device_type,
const bool  timestamp_approx,
const bool  is_arrow = false 
)
inlineprivate

Definition at line 229 of file ExecuteTest.cpp.

References anonymous_namespace{ExecuteTest.cpp}::approx_eq(), CHECK, CHECK_EQ, anonymous_namespace{ExecuteTest.cpp}::g_use_row_iterator, inline_fp_null_val(), inline_int_null_val(), kBIGINT, kBOOLEAN, kCHAR, kDATE, kDECIMAL, kDOUBLE, kFLOAT, kINT, kMilliSecsPerSec, kNUMERIC, kSMALLINT, kTEXT, kTIME, kTIMESTAMP, kTINYINT, kVARCHAR, num_rows, anonymous_namespace{ExecuteTest.cpp}::parse_fractional_seconds(), and split().

233  {
234  connector_.query(sqlite_query_string);
235  ASSERT_EQ(connector_.getNumRows(), mapd_results->rowCount());
236  const int num_rows{static_cast<int>(connector_.getNumRows())};
237  if (mapd_results->definitelyHasNoRows()) {
238  ASSERT_EQ(0, num_rows);
239  return;
240  }
241  if (!num_rows) {
242  return;
243  }
244  CHECK_EQ(connector_.getNumCols(), mapd_results->colCount());
245  const int num_cols{static_cast<int>(connector_.getNumCols())};
246  auto row_iterator = mapd_results->rowIterator(true, true);
247  for (int row_idx = 0; row_idx < num_rows; ++row_idx) {
248  const auto crt_row =
249  g_use_row_iterator ? *row_iterator++ : mapd_results->getNextRow(true, true);
250  CHECK(!crt_row.empty());
251  CHECK_EQ(static_cast<size_t>(num_cols), crt_row.size());
252  for (int col_idx = 0; col_idx < num_cols; ++col_idx) {
253  const auto ref_col_type = connector_.columnTypes[col_idx];
254  const auto mapd_variant = crt_row[col_idx];
255  const auto scalar_mapd_variant = boost::get<ScalarTargetValue>(&mapd_variant);
256  CHECK(scalar_mapd_variant);
257  auto mapd_ti = mapd_results->getColType(col_idx);
258  const auto mapd_type = mapd_ti.get_type();
259  checkTypeConsistency(ref_col_type, mapd_ti);
260  const bool ref_is_null = connector_.isNull(row_idx, col_idx);
261  switch (mapd_type) {
262  case kTINYINT:
263  case kSMALLINT:
264  case kINT:
265  case kBIGINT: {
266  const auto mapd_as_int_p = boost::get<int64_t>(scalar_mapd_variant);
267  ASSERT_NE(nullptr, mapd_as_int_p);
268  const auto mapd_val = *mapd_as_int_p;
269  if (ref_is_null) {
270  ASSERT_EQ(inline_int_null_val(mapd_ti), mapd_val);
271  } else {
272  const auto ref_val = connector_.getData<int64_t>(row_idx, col_idx);
273  ASSERT_EQ(ref_val, mapd_val);
274  }
275  break;
276  }
277  case kTEXT:
278  case kCHAR:
279  case kVARCHAR: {
280  const auto mapd_as_str_p = boost::get<NullableString>(scalar_mapd_variant);
281  ASSERT_NE(nullptr, mapd_as_str_p);
282  const auto mapd_str_notnull = boost::get<std::string>(mapd_as_str_p);
283  if (ref_is_null) {
284  // CHECK(!mapd_str_notnull); // JUST TO DEBUG SOMETHING TO BE UNCOMENTED
285  } else {
286  const auto ref_val = connector_.getData<std::string>(row_idx, col_idx);
287  if (mapd_str_notnull) {
288  const auto mapd_val = *mapd_str_notnull;
289  ASSERT_EQ(ref_val, mapd_val);
290  } else {
291  // not null but no data, so val is empty string
292  const auto mapd_val = "";
293  ASSERT_EQ(ref_val, mapd_val);
294  }
295  }
296  break;
297  }
298  case kNUMERIC:
299  case kDECIMAL:
300  case kDOUBLE: {
301  const auto mapd_as_double_p = boost::get<double>(scalar_mapd_variant);
302  ASSERT_NE(nullptr, mapd_as_double_p);
303  const auto mapd_val = *mapd_as_double_p;
304  if (ref_is_null) {
305  ASSERT_EQ(inline_fp_null_val(SQLTypeInfo(kDOUBLE, false)), mapd_val);
306  } else {
307  const auto ref_val = connector_.getData<double>(row_idx, col_idx);
308  ASSERT_TRUE(approx_eq(ref_val, mapd_val));
309  }
310  break;
311  }
312  case kFLOAT: {
313  const auto mapd_as_float_p = boost::get<float>(scalar_mapd_variant);
314  ASSERT_NE(nullptr, mapd_as_float_p);
315  const auto mapd_val = *mapd_as_float_p;
316  if (ref_is_null) {
317  ASSERT_EQ(inline_fp_null_val(SQLTypeInfo(kFLOAT, false)), mapd_val);
318  } else {
319  const auto ref_val = connector_.getData<float>(row_idx, col_idx);
320  ASSERT_TRUE(approx_eq(ref_val, mapd_val));
321  }
322  break;
323  }
324  case kTIMESTAMP:
325  case kDATE: {
326  const auto mapd_as_int_p = boost::get<int64_t>(scalar_mapd_variant);
327  CHECK(mapd_as_int_p);
328  const auto mapd_val = *mapd_as_int_p;
329  time_t nsec = 0;
330  const int dimen = mapd_ti.get_dimension();
331  if (ref_is_null) {
332  CHECK_EQ(inline_int_null_val(mapd_ti), mapd_val);
333  } else {
334  struct tm tm_struct {
335  0
336  };
337  const auto ref_val = connector_.getData<std::string>(row_idx, col_idx);
338  auto end_str =
339  strptime(ref_val.c_str(),
340  mapd_type == kTIMESTAMP ? "%Y-%m-%d %H:%M:%S" : "%Y-%m-%d",
341  &tm_struct);
342  // handle fractional seconds
343  if (end_str != nullptr && *end_str != '.') {
344  if (end_str) {
345  ASSERT_EQ(0, *end_str);
346  }
347  ASSERT_EQ(ref_val.size(), static_cast<size_t>(end_str - ref_val.c_str()));
348  }
349  if (dimen > 0 && mapd_type == kTIMESTAMP) {
350  int fs = 0;
351  if (*end_str == '.') {
352  end_str++;
353  uint frac_num;
354  int ntotal;
355  sscanf(end_str, "%d%n", &frac_num, &ntotal);
356  fs = parse_fractional_seconds(frac_num, ntotal, mapd_ti);
357  nsec = timegm(&tm_struct) * pow(10, dimen);
358  nsec += fs;
359  } else if (*end_str == '\0') {
360  nsec = timegm(&tm_struct) * pow(10, dimen);
361  } else {
362  CHECK(false);
363  }
364  }
365  if (timestamp_approx) {
366  // approximate result give 10 second lee way
367  ASSERT_NEAR(*mapd_as_int_p,
368  dimen > 0 ? nsec : timegm(&tm_struct),
369  dimen > 0 ? 10 * pow(10, dimen) : 10);
370  } else {
371  if (is_arrow && mapd_type == kDATE) {
372  ASSERT_EQ(*mapd_as_int_p, timegm(&tm_struct) * kMilliSecsPerSec);
373  } else {
374  ASSERT_EQ(*mapd_as_int_p, dimen > 0 ? nsec : timegm(&tm_struct));
375  }
376  }
377  }
378  break;
379  }
380  case kBOOLEAN: {
381  const auto mapd_as_int_p = boost::get<int64_t>(scalar_mapd_variant);
382  CHECK(mapd_as_int_p);
383  const auto mapd_val = *mapd_as_int_p;
384  if (ref_is_null) {
385  CHECK_EQ(inline_int_null_val(mapd_ti), mapd_val);
386  } else {
387  const auto ref_val = connector_.getData<std::string>(row_idx, col_idx);
388  if (ref_val == "t") {
389  ASSERT_EQ(1, *mapd_as_int_p);
390  } else {
391  CHECK_EQ("f", ref_val);
392  ASSERT_EQ(0, *mapd_as_int_p);
393  }
394  }
395  break;
396  }
397  case kTIME: {
398  const auto mapd_as_int_p = boost::get<int64_t>(scalar_mapd_variant);
399  CHECK(mapd_as_int_p);
400  const auto mapd_val = *mapd_as_int_p;
401  if (ref_is_null) {
402  CHECK_EQ(inline_int_null_val(mapd_ti), mapd_val);
403  } else {
404  const auto ref_val = connector_.getData<std::string>(row_idx, col_idx);
405  std::vector<std::string> time_tokens;
406  boost::split(time_tokens, ref_val, boost::is_any_of(":"));
407  ASSERT_EQ(size_t(3), time_tokens.size());
408  ASSERT_EQ(boost::lexical_cast<int64_t>(time_tokens[0]) * 3600 +
409  boost::lexical_cast<int64_t>(time_tokens[1]) * 60 +
410  boost::lexical_cast<int64_t>(time_tokens[2]),
411  *mapd_as_int_p);
412  }
413  break;
414  }
415  default:
416  CHECK(false);
417  }
418  }
419  }
420  }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
int parse_fractional_seconds(uint sfrac, int ntotal, SQLTypeInfo &ti)
T getData(const int row, const int col)
const int8_t const int64_t * num_rows
Definition: sqltypes.h:51
bool approx_eq(const double v, const double target, const double eps=0.01)
void query(const std::string &queryString)
static void checkTypeConsistency(const int ref_col_type, const SQLTypeInfo &mapd_ti)
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
size_t getNumRows() const
static constexpr int64_t kMilliSecsPerSec
size_t getNumCols() const
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
std::vector< int > columnTypes
Definition: sqltypes.h:54
Definition: sqltypes.h:55
std::vector< std::string > split(const std::string &str, const std::string &delim)
Definition: sqltypes.h:43
bool isNull(const int row, const int col) const
#define CHECK(condition)
Definition: Logger.h:187
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
Definition: sqltypes.h:47
+ Here is the call graph for this function:

◆ compare_timstamp_approx()

void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::compare_timstamp_approx ( const std::string &  query_string,
const ExecutorDeviceType  device_type 
)
inline

Definition at line 221 of file ExecuteTest.cpp.

References run_multiple_agg().

Referenced by anonymous_namespace{ExecuteTest.cpp}::cta().

222  {
223  const auto mapd_results = run_multiple_agg(query_string, device_type);
224  compare_impl(mapd_results.get(), query_string, device_type, true);
225  }
void compare_impl(const MapDResults *mapd_results, const std::string &sqlite_query_string, const ExecutorDeviceType device_type, const bool timestamp_approx, const bool is_arrow=false)
std::shared_ptr< ResultSet > run_multiple_agg(const string &query_str, const ExecutorDeviceType device_type, const bool allow_loop_joins)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query()

void anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::query ( const std::string &  query_string)
inline

Definition at line 197 of file ExecuteTest.cpp.

Referenced by anonymous_namespace{ExecuteTest.cpp}::create_and_populate_rounding_table(), anonymous_namespace{ExecuteTest.cpp}::create_and_populate_tables(), anonymous_namespace{ExecuteTest.cpp}::create_and_populate_window_func_table(), anonymous_namespace{ExecuteTest.cpp}::create_as_select(), anonymous_namespace{ExecuteTest.cpp}::create_as_select_empty(), anonymous_namespace{ExecuteTest.cpp}::create_sharded_join_table(), anonymous_namespace{ExecuteTest.cpp}::create_views(), anonymous_namespace{ExecuteTest.cpp}::drop_tables(), anonymous_namespace{ExecuteTest.cpp}::drop_views(), anonymous_namespace{ExecuteTest.cpp}::import_big_decimal_range_test(), anonymous_namespace{ExecuteTest.cpp}::import_coalesce_cols_join_test(), anonymous_namespace{ExecuteTest.cpp}::import_decimal_compression_test(), anonymous_namespace{ExecuteTest.cpp}::import_dept_table(), anonymous_namespace{ExecuteTest.cpp}::import_emp_table(), anonymous_namespace{ExecuteTest.cpp}::import_empty_table_test(), anonymous_namespace{ExecuteTest.cpp}::import_gpu_sort_test(), anonymous_namespace{ExecuteTest.cpp}::import_hash_join_test(), anonymous_namespace{ExecuteTest.cpp}::import_join_test(), anonymous_namespace{ExecuteTest.cpp}::import_logical_size_test(), anonymous_namespace{ExecuteTest.cpp}::import_query_rewrite_test(), anonymous_namespace{ExecuteTest.cpp}::import_subquery_test(), anonymous_namespace{ExecuteTest.cpp}::import_test_table_with_lots_of_columns(), and TEST().

197 { connector_.query(query_string); }
void query(const std::string &queryString)
+ Here is the caller graph for this function:

Member Data Documentation

◆ connector_

SqliteConnector anonymous_namespace{ExecuteTest.cpp}::SQLiteComparator::connector_
private

Definition at line 438 of file ExecuteTest.cpp.


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