OmniSciDB  c07336695a
CtasUpdateTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018, OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "../QueryRunner/QueryRunner.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <ctime>
22 #include <iostream>
23 #include "../Parser/parser.h"
24 #include "../QueryEngine/ArrowResultSet.h"
25 #include "../QueryEngine/Execute.h"
26 #include "../Shared/file_delete.h"
27 #include "TestHelpers.h"
28 
29 #include "../Shared/ConfigResolve.h"
30 
31 // uncomment to run full test suite
32 // #define RUN_ALL_TEST
33 
34 #ifndef BASE_PATH
35 #define BASE_PATH "./tmp"
36 #endif
37 
39 
41  public:
42  virtual std::string get_column_definition() = 0;
43  virtual std::string get_column_value(int row) = 0;
44  virtual std::string get_update_column_value(int row) { return get_column_value(row); }
45 
46  virtual bool check_column_value(const int row,
47  const SQLTypeInfo& type,
48  const ScalarTargetValue* scalarValue) = 0;
49  virtual bool check_column_value(const int row,
50  const SQLTypeInfo& type,
51  const TargetValue* value) {
52  const auto scalar_mapd_variant = boost::get<ScalarTargetValue>(value);
53  if (nullptr == scalar_mapd_variant) {
54  return false;
55  }
56 
57  return check_column_value(row, type, scalar_mapd_variant);
58  }
59  virtual ~TestColumnDescriptor() = default;
60 
61  virtual bool skip_test(std::string name) { return false; }
62 };
63 
64 template <typename T>
66  std::string column_definition;
67  SQLTypes rs_type;
68  T null_value;
69 
70  public:
71  NumberColumnDescriptor(std::string col_type, SQLTypes sql_type, T null)
72  : column_definition(col_type), rs_type(sql_type), null_value(null){};
73 
74  bool skip_test(std::string name) override {
75  if (kDECIMAL == rs_type) {
76  return "Array.UpdateColumnByLiteral" == name;
77  }
78  if (kDOUBLE == rs_type || kFLOAT == rs_type) {
79  return "Array.UpdateColumnByLiteral" == name;
80  }
81  return false;
82  }
83 
84  std::string get_column_definition() override { return column_definition; };
85  std::string get_column_value(int row) override {
86  if (0 == row) {
87  return "null";
88  }
89 
90  return std::to_string(row);
91  };
92  bool check_column_value(int row,
93  const SQLTypeInfo& type,
94  const ScalarTargetValue* value) override {
95  if (type.get_type() != rs_type) {
96  return false;
97  }
98 
99  const auto mapd_as_int_p = boost::get<T>(value);
100  if (nullptr == mapd_as_int_p) {
101  LOG(ERROR) << "row: null";
102  return false;
103  }
104 
105  const auto mapd_val = *mapd_as_int_p;
106 
107  T value_to_check = (T)row;
108  if (row == 0) {
109  value_to_check = null_value;
110  } else if (kDECIMAL == rs_type) {
111  // TODO: create own descriptor for decimals
112  value_to_check *= pow10(type.get_scale());
113  }
114 
115  if (mapd_val == value_to_check) {
116  return true;
117  }
118 
119  LOG(ERROR) << "row: " << std::to_string(row) << " " << std::to_string(value_to_check)
120  << " vs. " << std::to_string(mapd_val);
121  return false;
122  }
123 
124  int64_t pow10(int scale) {
125  int64_t pow = 1;
126  for (int i = 0; i < scale; i++) {
127  pow *= 10;
128  }
129 
130  return pow;
131  }
132 };
133 
135  std::string column_definition;
137 
138  public:
139  BooleanColumnDescriptor(std::string col_type, SQLTypes sql_type)
140  : column_definition(col_type), rs_type(sql_type){};
141 
142  bool skip_test(std::string name) override {
143  return "UpdateColumnByLiteral" == name || "Array.UpdateColumnByLiteral" == name;
144  }
145 
146  std::string get_column_definition() override { return column_definition; };
147  std::string get_column_value(int row) override {
148  if (0 == row) {
149  return "null";
150  }
151 
152  return (row % 2) ? "'true'" : "'false'";
153  };
154  bool check_column_value(int row,
155  const SQLTypeInfo& type,
156  const ScalarTargetValue* value) override {
157  if (type.get_type() != rs_type) {
158  return false;
159  }
160 
161  const auto mapd_as_int_p = boost::get<int64_t>(value);
162  if (nullptr == mapd_as_int_p) {
163  LOG(ERROR) << "row: null";
164  return false;
165  }
166 
167  const auto mapd_val = *mapd_as_int_p;
168 
169  int64_t value_to_check = (row % 2);
170  if (row == 0) {
171  value_to_check = NULL_TINYINT;
172  }
173 
174  if (mapd_val == value_to_check) {
175  return true;
176  }
177 
178  LOG(ERROR) << "row: " << std::to_string(row) << " " << std::to_string(value_to_check)
179  << " vs. " << std::to_string(mapd_val);
180  return false;
181  }
182 };
183 
185  std::string column_definition;
187  std::string prefix;
188 
189  public:
190  StringColumnDescriptor(std::string col_type, SQLTypes sql_type, std::string pfix)
191  : column_definition(col_type), rs_type(sql_type), prefix(pfix){};
192 
193  bool skip_test(std::string name) override {
194  return "Array.UpdateColumnByLiteral" == name;
195  }
196 
197  std::string get_column_definition() override { return column_definition; };
198  std::string get_column_value(int row) override {
199  if (0 == row) {
200  return "null";
201  }
202 
203  return "'" + prefix + "_" + std::to_string(row) + "'";
204  };
205  bool check_column_value(int row,
206  const SQLTypeInfo& type,
207  const ScalarTargetValue* value) override {
208  if (!(type.get_type() == rs_type || type.get_type() == kTEXT)) {
209  return false;
210  }
211 
212  const auto mapd_as_str_p = boost::get<NullableString>(value);
213  if (nullptr == mapd_as_str_p) {
214  return false;
215  }
216 
217  const auto mapd_str_p = boost::get<std::string>(mapd_as_str_p);
218  if (nullptr == mapd_str_p) {
219  return 0 == row;
220  }
221 
222  const auto mapd_val = *mapd_str_p;
223  if (row == 0) {
224  if (mapd_val == "") {
225  return true;
226  }
227  } else if (mapd_val == (prefix + "_" + std::to_string(row))) {
228  return true;
229  }
230 
231  LOG(ERROR) << "row: " << std::to_string(row) << " "
232  << (prefix + "_" + std::to_string(row)) << " vs. " << mapd_val;
233  return false;
234  }
235 };
236 
238  std::string column_definition;
239  SQLTypes rs_type;
240  std::string format;
241  long offset;
242  long scale;
243 
244  public:
245  DateTimeColumnDescriptor(std::string col_type,
246  SQLTypes sql_type,
247  std::string fmt,
248  long offset,
249  int scale)
250  : column_definition(col_type)
251  , rs_type(sql_type)
252  , format(fmt)
253  , offset(offset)
254  , scale(scale){};
255 
256  bool skip_test(std::string name) override {
257  return "Array.UpdateColumnByLiteral" == name;
258  }
259 
260  std::string get_column_definition() override { return column_definition; };
261  std::string get_column_value(int row) override {
262  if (0 == row) {
263  return "null";
264  }
265 
266  return "'" + getValueAsString(row) + "'";
267  };
268  bool check_column_value(int row,
269  const SQLTypeInfo& type,
270  const ScalarTargetValue* value) override {
271  if (type.get_type() != rs_type) {
272  return false;
273  }
274 
275  const auto mapd_as_int_p = boost::get<int64_t>(value);
276  if (nullptr == mapd_as_int_p) {
277  return 0 == row;
278  }
279 
280  const auto mapd_val = *mapd_as_int_p;
281 
282  int64_t value_to_check = (offset + (scale * row));
283  if (rs_type == kDATE) {
284  value_to_check /= (24 * 60 * 60);
285  value_to_check *= (24 * 60 * 60);
286  }
287  if (row == 0) {
288  value_to_check = NULL_BIGINT;
289  }
290 
291  if (mapd_val == value_to_check) {
292  return true;
293  }
294 
295  LOG(ERROR) << "row: " << std::to_string(row) << " "
296  << std::to_string((offset + (scale * row))) << " vs. "
297  << std::to_string(mapd_val);
298  return false;
299  }
300 
301  std::string getValueAsString(int row) {
302  std::tm tm_struct;
303  time_t t = offset + (scale * row);
304  gmtime_r(&t, &tm_struct);
305  char buf[128];
306  strftime(buf, 128, format.c_str(), &tm_struct);
307  return std::string(buf);
308  }
309 };
310 
312  public:
313  std::string column_definition;
314  const std::shared_ptr<TestColumnDescriptor> element_descriptor;
315  int fixed_array_length;
316 
317  ArrayColumnDescriptor(std::string def,
318  const std::shared_ptr<TestColumnDescriptor> columnDesc,
319  int fixed_len = 0)
320  : column_definition(def +
321  (fixed_len ? "[" + std::to_string(fixed_len) + "]" : "[]"))
322  , element_descriptor(columnDesc)
323  , fixed_array_length(fixed_len) {}
324 
325  bool skip_test(std::string name) override {
326  return element_descriptor->skip_test("Array." + name);
327  }
328 
329  std::string get_column_definition() override { return column_definition; }
330 
331  std::string make_column_value(int rows, std::string prefix, std::string suffix) {
332  std::string values = prefix;
333 
334  int i = 0;
335 
336  if (fixed_array_length) {
337  i = rows;
338  rows += fixed_array_length;
339  }
340 
341  bool firstElementWritten = false;
342 
343  for (; i < rows; i++) {
344  if (firstElementWritten) {
345  values += ", ";
346  }
347  values += element_descriptor->get_column_value(i + 1);
348  firstElementWritten = true;
349  }
350  values += suffix;
351 
352  return values;
353  }
354 
355  std::string get_column_value(int row) override {
356  return make_column_value(row + 1, "{", "}");
357  }
358 
359  std::string get_update_column_value(int row) override {
360  return make_column_value(row + 1, "ARRAY[", "]");
361  }
362 
363  bool check_column_value(const int row,
364  const SQLTypeInfo& type,
365  const TargetValue* value) override {
366  auto arrayValue = boost::get<ArrayTargetValue>(value);
367 
368  if (!arrayValue) {
369  return false;
370  }
371  if (!arrayValue->is_initialized()) {
372  return true; // NULL array, nothing to check
373  }
374 
375  const SQLTypeInfo subtype = type.get_elem_type();
376 
377  int elementIndex = 1;
378 
379  if (fixed_array_length) {
380  elementIndex += row + 1;
381  }
382 
383  const auto& vec = arrayValue->get();
384  for (auto& scalarValue : vec) {
385  if (!element_descriptor->check_column_value(elementIndex, subtype, &scalarValue)) {
386  return false;
387  }
388 
389  elementIndex++;
390  }
391 
392  return true;
393  }
394 
395  bool check_column_value(const int row,
396  const SQLTypeInfo& type,
397  const ScalarTargetValue* scalarValue) override {
398  return false;
399  }
400 };
401 
404  std::string prefix;
405 
406  public:
407  GeoPointColumnDescriptor(SQLTypes sql_type = kPOINT) : rs_type(sql_type){};
408 
409  bool skip_test(std::string name) override { return "CreateTableAsSelect" != name; }
410 
411  std::string get_column_definition() override { return "POINT"; };
412 
413  std::string getColumnWktStringValue(int row) {
414  return "POINT (" + std::to_string(row) + " 0)";
415  }
416  std::string get_column_value(int row) override {
417  return "'" + getColumnWktStringValue(row) + "'";
418  };
419 
420  bool check_column_value(int row,
421  const SQLTypeInfo& type,
422  const ScalarTargetValue* value) override {
423  if (!(type.get_type() == rs_type)) {
424  return false;
425  }
426 
427  const auto mapd_as_str_p = boost::get<NullableString>(value);
428  if (nullptr == mapd_as_str_p) {
429  return false;
430  }
431 
432  const auto mapd_str_p = boost::get<std::string>(mapd_as_str_p);
433  if (nullptr == mapd_str_p) {
434  return false;
435  }
436 
437  const auto mapd_val = *mapd_str_p;
438  if (mapd_val == getColumnWktStringValue(row)) {
439  return true;
440  }
441 
442  LOG(ERROR) << "row: " << std::to_string(row) << " " << getColumnWktStringValue(row)
443  << " vs. " << mapd_val;
444  return false;
445  }
446 };
447 
450  std::string prefix;
451 
452  public:
453  GeoLinestringColumnDescriptor(SQLTypes sql_type = kLINESTRING) : rs_type(sql_type){};
454 
455  bool skip_test(std::string name) override { return "CreateTableAsSelect" != name; }
456 
457  std::string get_column_definition() override { return "LINESTRING"; };
458 
459  std::string getColumnWktStringValue(int row) {
460  std::string linestring = "LINESTRING (0 0";
461  for (int i = 0; i <= row; i++) {
462  linestring += "," + std::to_string(row) + " 0";
463  }
464  linestring += ")";
465  return linestring;
466  }
467  std::string get_column_value(int row) override {
468  return "'" + getColumnWktStringValue(row) + "'";
469  };
470 
471  bool check_column_value(int row,
472  const SQLTypeInfo& type,
473  const ScalarTargetValue* value) override {
474  if (!(type.get_type() == rs_type)) {
475  return false;
476  }
477 
478  const auto mapd_as_str_p = boost::get<NullableString>(value);
479  if (nullptr == mapd_as_str_p) {
480  return false;
481  }
482 
483  const auto mapd_str_p = boost::get<std::string>(mapd_as_str_p);
484  if (nullptr == mapd_str_p) {
485  return false;
486  }
487 
488  const auto mapd_val = *mapd_str_p;
489  if (mapd_val == getColumnWktStringValue(row)) {
490  return true;
491  }
492 
493  LOG(ERROR) << "row: " << std::to_string(row) << " " << getColumnWktStringValue(row)
494  << " vs. " << mapd_val;
495  return false;
496  }
497 };
498 
501  std::string prefix;
502 
503  public:
505  : rs_type(sql_type){};
506 
507  bool skip_test(std::string name) override { return "CreateTableAsSelect" != name; }
508 
509  std::string get_column_definition() override { return "MULTIPOLYGON"; };
510 
511  std::string getColumnWktStringValue(int row) {
512  std::string polygon =
513  "MULTIPOLYGON (((0 " + std::to_string(row) + ",4 " + std::to_string(row) + ",4 " +
514  std::to_string(row + 4) + ",0 " + std::to_string(row + 4) + ",0 " +
515  std::to_string(row) + "),(1 " + std::to_string(row + 1) + ",1 " +
516  std::to_string(row + 2) + ",2 " + std::to_string(row + 2) + ",2 " +
517  std::to_string(row + 1) + ",1 " + std::to_string(row + 1) + ")))";
518  return polygon;
519  }
520 
521  std::string get_column_value(int row) override {
522  return "'" + getColumnWktStringValue(row) + "'";
523  };
524 
525  bool check_column_value(int row,
526  const SQLTypeInfo& type,
527  const ScalarTargetValue* value) override {
528  if (!(type.get_type() == rs_type)) {
529  return false;
530  }
531 
532  const auto mapd_as_str_p = boost::get<NullableString>(value);
533  if (nullptr == mapd_as_str_p) {
534  return false;
535  }
536 
537  const auto mapd_str_p = boost::get<std::string>(mapd_as_str_p);
538  if (nullptr == mapd_str_p) {
539  return false;
540  }
541 
542  const auto mapd_val = *mapd_str_p;
543  if (mapd_val == getColumnWktStringValue(row)) {
544  return true;
545  }
546 
547  LOG(ERROR) << "row: " << std::to_string(row) << " " << getColumnWktStringValue(row)
548  << " vs. " << mapd_val;
549  return false;
550  }
551 };
552 
555  std::string prefix;
556 
557  public:
558  GeoPolygonColumnDescriptor(SQLTypes sql_type = kPOLYGON) : rs_type(sql_type){};
559 
560  bool skip_test(std::string name) override { return "CreateTableAsSelect" != name; }
561 
562  std::string get_column_definition() override { return "POLYGON"; };
563 
564  std::string getColumnWktStringValue(int row) {
565  std::string polygon =
566  "POLYGON ((0 " + std::to_string(row) + ",4 " + std::to_string(row) + ",4 " +
567  std::to_string(row + 4) + ",0 " + std::to_string(row + 4) + ",0 " +
568  std::to_string(row) + "),(1 " + std::to_string(row + 1) + ",1 " +
569  std::to_string(row + 2) + ",2 " + std::to_string(row + 2) + ",2 " +
570  std::to_string(row + 1) + ",1 " + std::to_string(row + 1) + "))";
571  return polygon;
572  }
573 
574  std::string get_column_value(int row) override {
575  return "'" + getColumnWktStringValue(row) + "'";
576  };
577 
578  bool check_column_value(int row,
579  const SQLTypeInfo& type,
580  const ScalarTargetValue* value) override {
581  if (!(type.get_type() == rs_type)) {
582  return false;
583  }
584 
585  const auto mapd_as_str_p = boost::get<NullableString>(value);
586  if (nullptr == mapd_as_str_p) {
587  return false;
588  }
589 
590  const auto mapd_str_p = boost::get<std::string>(mapd_as_str_p);
591  if (nullptr == mapd_str_p) {
592  return false;
593  }
594 
595  const auto mapd_val = *mapd_str_p;
596  if (mapd_val == getColumnWktStringValue(row)) {
597  return true;
598  }
599 
600  LOG(ERROR) << "row: " << std::to_string(row) << " " << getColumnWktStringValue(row)
601  << " vs. " << mapd_val;
602  return false;
603  }
604 };
605 
606 struct Ctas
607  : testing::Test,
608  testing::WithParamInterface<std::vector<std::shared_ptr<TestColumnDescriptor>>> {
609  std::vector<std::shared_ptr<TestColumnDescriptor>> columnDescriptors;
610 
611  Ctas() { columnDescriptors = GetParam(); }
612 };
613 
614 struct Itas
615  : testing::Test,
616  testing::WithParamInterface<std::vector<std::shared_ptr<TestColumnDescriptor>>> {
617  std::vector<std::shared_ptr<TestColumnDescriptor>> columnDescriptors;
618 
619  Itas() { columnDescriptors = GetParam(); }
620 };
621 
622 struct Update
623  : testing::Test,
624  testing::WithParamInterface<std::vector<std::shared_ptr<TestColumnDescriptor>>> {
625  std::vector<std::shared_ptr<TestColumnDescriptor>> columnDescriptors;
626 
627  Update() { columnDescriptors = GetParam(); }
628 };
629 
630 namespace {
631 
632 void run_ddl_statement(const std::string& stmt) {
633  QR::get()->runDDLStatement(stmt);
634 }
635 
636 std::shared_ptr<ResultSet> run_multiple_agg(const std::string& sql,
637  const ExecutorDeviceType dt) {
638  return QR::get()->runSQL(sql, ExecutorDeviceType::CPU, true, true);
639 }
640 
641 } // namespace
642 
643 TEST(Ctas, SyntaxCheck) {
644  std::string ddl = "DROP TABLE IF EXISTS CTAS_SOURCE;";
645  run_ddl_statement(ddl);
646  ddl = "DROP TABLE IF EXISTS CTAS_TARGET;";
647  run_ddl_statement(ddl);
648 
649  run_ddl_statement("CREATE TABLE CTAS_SOURCE (id int);");
650 
651  ddl = "CREATE TABLE CTAS_TARGET AS SELECT * FROM CTAS_SOURCE;";
652  run_ddl_statement(ddl);
653  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
654  ddl = "DROP TABLE CTAS_TARGET;";
655  run_ddl_statement(ddl);
656 
657  ddl = "CREATE TEMPORARY TABLE CTAS_TARGET AS SELECT * FROM CTAS_SOURCE;";
658  run_ddl_statement(ddl);
659  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
660  ddl = "DROP TABLE CTAS_TARGET;";
661  run_ddl_statement(ddl);
662 
663  ddl = "CREATE TABLE CTAS_TARGET AS SELECT * FROM CTAS_SOURCE WITH( FRAGMENT_SIZE=3 );";
664  run_ddl_statement(ddl);
665  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
666  ddl = "DROP TABLE CTAS_TARGET;";
667  run_ddl_statement(ddl);
668 
669  ddl = "CREATE TABLE CTAS_TARGET AS SELECT * FROM CTAS_SOURCE WITH( MAX_CHUNK_SIZE=3 );";
670  run_ddl_statement(ddl);
671  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
672  ddl = "DROP TABLE CTAS_TARGET;";
673  run_ddl_statement(ddl);
674 }
675 
676 TEST(Ctas, LiteralStringTest) {
677  std::string ddl = "DROP TABLE IF EXISTS CTAS_SOURCE;";
678  run_ddl_statement(ddl);
679  ddl = "DROP TABLE IF EXISTS CTAS_TARGET;";
680  run_ddl_statement(ddl);
681 
682  run_ddl_statement("CREATE TABLE CTAS_SOURCE (id int, val int);");
683 
684  run_multiple_agg("INSERT INTO CTAS_SOURCE VALUES(1,1); ", ExecutorDeviceType::CPU);
685  run_multiple_agg("INSERT INTO CTAS_SOURCE VALUES(2,2); ", ExecutorDeviceType::CPU);
686  run_multiple_agg("INSERT INTO CTAS_SOURCE VALUES(3,3); ", ExecutorDeviceType::CPU);
687 
688  ddl =
689  "CREATE TABLE CTAS_TARGET AS select id, val, (case when val=1 then 'aa' else 'bb' "
690  "end) as txt FROM CTAS_SOURCE;";
691  run_ddl_statement(ddl);
692 
693  auto check = [](int id, std::string txt) {
694  auto select_result = run_multiple_agg(
695  "SELECT txt FROM CTAS_TARGET WHERE id=" + std::to_string(id) + ";",
697 
698  const auto select_crt_row = select_result->getNextRow(true, false);
699  const auto mapd_variant = select_crt_row[0];
700  const auto scalar_mapd_variant = boost::get<ScalarTargetValue>(&mapd_variant);
701  const auto mapd_as_str_p = boost::get<NullableString>(scalar_mapd_variant);
702  const auto mapd_str_p = boost::get<std::string>(mapd_as_str_p);
703  const auto mapd_val = *mapd_str_p;
704  ASSERT_EQ(txt, mapd_val);
705  };
706 
707  check(1, "aa");
708  check(2, "bb");
709  check(3, "bb");
710 }
711 
712 TEST_P(Ctas, CreateTableAsSelect) {
713  run_ddl_statement("DROP TABLE IF EXISTS CTAS_SOURCE;");
714  run_ddl_statement("DROP TABLE IF EXISTS CTAS_TARGET;");
715 
716  std::string create_sql = "CREATE TABLE CTAS_SOURCE (id int";
717  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
718  auto tcd = columnDescriptors[col];
719  if (tcd->skip_test("CreateTableAsSelect")) {
720  LOG(ERROR) << "not supported... skipping";
721  return;
722  }
723 
724  create_sql += ", col_" + std::to_string(col) + " " + tcd->get_column_definition();
725  }
726  create_sql += ");";
727 
728  LOG(INFO) << create_sql;
729 
730  run_ddl_statement(create_sql);
731 
732  size_t num_rows = 25;
733 
734  // fill source table
735  for (unsigned int row = 0; row < num_rows; row++) {
736  std::string insert_sql = "INSERT INTO CTAS_SOURCE VALUES (" + std::to_string(row);
737  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
738  auto tcd = columnDescriptors[col];
739  insert_sql += ", " + tcd->get_column_value(row);
740  }
741  insert_sql += ");";
742 
744  }
745 
746  // execute CTAS
747  std::string create_ctas_sql = "CREATE TABLE CTAS_TARGET AS SELECT * FROM CTAS_SOURCE;";
748  LOG(INFO) << create_ctas_sql;
749 
750  run_ddl_statement(create_ctas_sql);
751 
752  // check tables
753  auto cat = QR::get()->getCatalog();
754  const TableDescriptor* td_source = cat->getMetadataForTable("CTAS_SOURCE");
755  const TableDescriptor* td_target = cat->getMetadataForTable("CTAS_TARGET");
756 
757  auto source_cols =
758  cat->getAllColumnMetadataForTable(td_source->tableId, false, true, false);
759  auto target_cols =
760  cat->getAllColumnMetadataForTable(td_target->tableId, false, true, false);
761 
762  ASSERT_EQ(source_cols.size(), target_cols.size());
763 
764  while (source_cols.size()) {
765  auto source_col = source_cols.back();
766  auto target_col = target_cols.back();
767 
768  LOG(INFO) << "Checking: " << source_col->columnName << " vs. "
769  << target_col->columnName << " ( " << source_col->columnType.get_type_name()
770  << " vs. " << target_col->columnType.get_type_name() << " )";
771 
772  // ASSERT_EQ(source_col->columnType.get_type(), target_col->columnType.get_type());
773  // ASSERT_EQ(source_col->columnType.get_elem_type(),
774  // target_col->columnType.get_elem_type());
775  ASSERT_EQ(source_col->columnType.get_compression(),
776  target_col->columnType.get_compression());
777  ASSERT_EQ(source_col->columnType.get_size(), target_col->columnType.get_size());
778 
779  source_cols.pop_back();
780  target_cols.pop_back();
781  }
782 
783  // compare source against CTAS
784  std::string select_sql = "SELECT * FROM CTAS_SOURCE ORDER BY id;";
785  std::string select_ctas_sql = "SELECT * FROM CTAS_TARGET ORDER BY id;";
786 
787  LOG(INFO) << select_sql;
788  auto select_result = run_multiple_agg(select_sql, ExecutorDeviceType::CPU);
789 
790  LOG(INFO) << select_ctas_sql;
791  auto select_ctas_result = run_multiple_agg(select_ctas_sql, ExecutorDeviceType::CPU);
792 
793  ASSERT_EQ(num_rows, select_result->rowCount());
794  ASSERT_EQ(num_rows, select_ctas_result->rowCount());
795 
796  for (unsigned int row = 0; row < num_rows; row++) {
797  const auto select_crt_row = select_result->getNextRow(true, false);
798  const auto select_ctas_crt_row = select_ctas_result->getNextRow(true, false);
799 
800  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
801  auto tcd = columnDescriptors[col];
802 
803  {
804  const auto mapd_variant = select_crt_row[col + 1];
805  auto mapd_ti = select_result->getColType(col + 1);
806  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
807  }
808  {
809  const auto mapd_variant = select_ctas_crt_row[col + 1];
810  auto mapd_ti = select_ctas_result->getColType(col + 1);
811  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
812  }
813  }
814  }
815 }
816 
817 TEST(Itas, SyntaxCheck) {
818  std::string ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
819  run_ddl_statement(ddl);
820  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
821  run_ddl_statement(ddl);
822 
823  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int, val int);");
824  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int);");
825 
826  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
827  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
828 
829  ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
830  run_ddl_statement(ddl);
831  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
832  run_ddl_statement(ddl);
833 
834  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int);");
835  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int, val int);");
836 
837  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
838  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
839 
840  ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
841  run_ddl_statement(ddl);
842  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
843  run_ddl_statement(ddl);
844 
845  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int);");
846  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int encoding FIXED(8));");
847 
848  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
849  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
850 
851  ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
852  run_ddl_statement(ddl);
853  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
854  run_ddl_statement(ddl);
855 
856  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int encoding FIXED(8));");
857  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int);");
858 
859  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
860  EXPECT_NO_THROW(run_ddl_statement(ddl));
861 
862  ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
863  run_ddl_statement(ddl);
864  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
865  run_ddl_statement(ddl);
866 
867  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int, val timestamp(0));");
868  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int, val timestamp(3));");
869 
870  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
871  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
872 
873  ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
874  run_ddl_statement(ddl);
875  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
876  run_ddl_statement(ddl);
877 
878  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int, val text encoding none);");
879  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int, val text);");
880 
881  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
882  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
883 
884  ddl = "DROP TABLE IF EXISTS ITAS_SOURCE;";
885  run_ddl_statement(ddl);
886  ddl = "DROP TABLE IF EXISTS ITAS_TARGET;";
887  run_ddl_statement(ddl);
888 
889  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int, val decimal(10,2));");
890  run_ddl_statement("CREATE TABLE ITAS_TARGET (id int, val decimal(10,3));");
891 
892  ddl = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
893  EXPECT_THROW(run_ddl_statement(ddl), std::runtime_error);
894 }
895 
896 TEST(Itas, DifferentColumnNames) {
897  run_ddl_statement("DROP TABLE IF EXISTS ITAS_SOURCE;");
898 
899  run_ddl_statement("CREATE TABLE ITAS_SOURCE (id int, val int);");
900 
901  run_multiple_agg("INSERT INTO ITAS_SOURCE VALUES(1,10); ", ExecutorDeviceType::CPU);
902  run_multiple_agg("INSERT INTO ITAS_SOURCE VALUES(2,20); ", ExecutorDeviceType::CPU);
903  run_multiple_agg("INSERT INTO ITAS_SOURCE VALUES(3,30); ", ExecutorDeviceType::CPU);
904 
905  auto check = [](int id, int64_t val) {
906  auto select_result = run_multiple_agg(
907  "SELECT target_val FROM ITAS_TARGET WHERE target_id=" + std::to_string(id) + ";",
909 
910  const auto select_crt_row = select_result->getNextRow(true, false);
911  const auto mapd_variant = select_crt_row[0];
912  const auto scalar_mapd_variant = boost::get<ScalarTargetValue>(&mapd_variant);
913  const auto mapd_int_p = boost::get<int64_t>(scalar_mapd_variant);
914  const auto mapd_val = *mapd_int_p;
915  ASSERT_EQ(val, mapd_val);
916  };
917 
918  run_ddl_statement("DROP TABLE IF EXISTS ITAS_TARGET;");
919  run_ddl_statement("CREATE TABLE ITAS_TARGET (target_id int, target_val int);");
920  run_ddl_statement("INSERT INTO ITAS_TARGET SELECT id, val FROM ITAS_SOURCE;");
921 
922  check(1, 10);
923  check(2, 20);
924  check(3, 30);
925 
926  run_ddl_statement("DROP TABLE IF EXISTS ITAS_TARGET;");
927  run_ddl_statement("CREATE TABLE ITAS_TARGET (target_id int, target_val int);");
929  "INSERT INTO ITAS_TARGET (target_id, target_val) SELECT id, val FROM ITAS_SOURCE;");
930 
931  check(1, 10);
932  check(2, 20);
933  check(3, 30);
934 
935  run_ddl_statement("DROP TABLE IF EXISTS ITAS_TARGET;");
936  run_ddl_statement("CREATE TABLE ITAS_TARGET (target_id int, target_val int);");
938  "INSERT INTO ITAS_TARGET (target_val, target_id) SELECT val, id FROM ITAS_SOURCE;");
939 
940  check(1, 10);
941  check(2, 20);
942  check(3, 30);
943 
944  run_ddl_statement("DROP TABLE IF EXISTS ITAS_TARGET;");
945  run_ddl_statement("CREATE TABLE ITAS_TARGET (target_id int, target_val int);");
947  "INSERT INTO ITAS_TARGET (target_id, target_val) SELECT val, id FROM ITAS_SOURCE;");
948 
949  check(10, 1);
950  check(20, 2);
951  check(30, 3);
952 
953  run_ddl_statement("DROP TABLE IF EXISTS ITAS_TARGET;");
954  run_ddl_statement("CREATE TABLE ITAS_TARGET (target_id int, target_val int);");
956  "INSERT INTO ITAS_TARGET (target_val, target_id) SELECT id, val FROM ITAS_SOURCE;");
957 
958  check(10, 1);
959  check(20, 2);
960  check(30, 3);
961 }
962 
963 void itasTestBody(std::vector<std::shared_ptr<TestColumnDescriptor>>& columnDescriptors,
964  std::string targetPartitionScheme = ")") {
965  run_ddl_statement("DROP TABLE IF EXISTS ITAS_SOURCE;");
966  run_ddl_statement("DROP TABLE IF EXISTS ITAS_TARGET;");
967 
968  std::string create_source_sql = "CREATE TABLE ITAS_SOURCE (id int";
969  std::string create_target_sql = "CREATE TABLE ITAS_TARGET (id int";
970  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
971  auto tcd = columnDescriptors[col];
972  if (tcd->skip_test("CreateTableAsSelect")) {
973  LOG(ERROR) << "not supported... skipping";
974  return;
975  }
976 
977  create_source_sql +=
978  ", col_" + std::to_string(col) + " " + tcd->get_column_definition();
979  create_target_sql +=
980  ", col_" + std::to_string(col) + " " + tcd->get_column_definition();
981  }
982  create_source_sql += ");";
983  create_target_sql += targetPartitionScheme + ";";
984 
985  LOG(INFO) << create_source_sql;
986  LOG(INFO) << create_target_sql;
987 
988  run_ddl_statement(create_source_sql);
989  run_ddl_statement(create_target_sql);
990 
991  size_t num_rows = 25;
992 
993  // fill source table
994  for (unsigned int row = 0; row < num_rows; row++) {
995  std::string insert_sql = "INSERT INTO ITAS_SOURCE VALUES (" + std::to_string(row);
996  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
997  auto tcd = columnDescriptors[col];
998  insert_sql += ", " + tcd->get_column_value(row);
999  }
1000  insert_sql += ");";
1001 
1003  }
1004 
1005  // execute CTAS
1006  std::string insert_itas_sql = "INSERT INTO ITAS_TARGET SELECT * FROM ITAS_SOURCE;";
1007  LOG(INFO) << insert_itas_sql;
1008 
1009  run_ddl_statement(insert_itas_sql);
1010 
1011  // compare source against CTAS
1012  std::string select_sql = "SELECT * FROM ITAS_SOURCE ORDER BY id;";
1013  std::string select_itas_sql = "SELECT * FROM ITAS_TARGET ORDER BY id;";
1014 
1015  LOG(INFO) << select_sql;
1016  auto select_result = run_multiple_agg(select_sql, ExecutorDeviceType::CPU);
1017 
1018  LOG(INFO) << select_itas_sql;
1019  auto select_itas_result = run_multiple_agg(select_itas_sql, ExecutorDeviceType::CPU);
1020 
1021  ASSERT_EQ(num_rows, select_result->rowCount());
1022  ASSERT_EQ(num_rows, select_itas_result->rowCount());
1023 
1024  for (unsigned int row = 0; row < num_rows; row++) {
1025  const auto select_crt_row = select_result->getNextRow(true, false);
1026  const auto select_itas_crt_row = select_itas_result->getNextRow(true, false);
1027 
1028  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1029  auto tcd = columnDescriptors[col];
1030 
1031  {
1032  const auto mapd_variant = select_crt_row[col + 1];
1033  auto mapd_ti = select_result->getColType(col + 1);
1034  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
1035  }
1036  {
1037  const auto mapd_variant = select_itas_crt_row[col + 1];
1038  auto mapd_ti = select_itas_result->getColType(col + 1);
1039  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
1040  }
1041  }
1042  }
1043 }
1044 
1045 TEST_P(Itas, InsertIntoTableFromSelect) {
1046  itasTestBody(columnDescriptors, ")");
1047 }
1048 
1049 TEST_P(Itas, InsertIntoTableFromSelectReplicated) {
1050  itasTestBody(columnDescriptors, ") WITH (partitions='REPLICATED')");
1051 }
1052 
1053 TEST_P(Itas, InsertIntoTableFromSelectSharded) {
1054  itasTestBody(columnDescriptors,
1055  ", SHARD KEY (id)) WITH (shard_count = 4, partitions='SHARDED')");
1056 }
1057 
1058 TEST_P(Update, UpdateColumnByColumn) {
1059  // disable if varlen update is not enabled
1060  if (!is_feature_enabled<VarlenUpdates>()) {
1061  LOG(WARNING) << "skipping...";
1062  return;
1063  }
1064 
1065  run_ddl_statement("DROP TABLE IF EXISTS update_test;");
1066 
1067  std::string create_sql = "CREATE TABLE update_test(id int";
1068  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1069  auto tcd = columnDescriptors[col];
1070 
1071  if (tcd->skip_test("UpdateColumnByColumn")) {
1072  LOG(ERROR) << "not supported... skipping";
1073  return;
1074  }
1075 
1076  create_sql += ", col_src_" + std::to_string(col) + " " + tcd->get_column_definition();
1077  create_sql += ", col_dst_" + std::to_string(col) + " " + tcd->get_column_definition();
1078  }
1079  create_sql += ") WITH (fragment_size=3);";
1080 
1081  LOG(INFO) << create_sql;
1082 
1083  run_ddl_statement(create_sql);
1084 
1085  size_t num_rows = 10;
1086 
1087  // fill source table
1088  for (unsigned int row = 0; row < num_rows; row++) {
1089  std::string insert_sql = "INSERT INTO update_test VALUES (" + std::to_string(row);
1090  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1091  auto tcd = columnDescriptors[col];
1092  insert_sql += ", " + tcd->get_column_value(row);
1093  insert_sql += ", " + tcd->get_column_value(row + 1);
1094  }
1095  insert_sql += ");";
1096 
1098  }
1099 
1100  // execute Updates
1101  std::string update_sql = "UPDATE update_test set ";
1102  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1103  update_sql +=
1104  " col_dst_" + std::to_string(col) + "=" + "col_src_" + std::to_string(col);
1105  if (col + 1 < columnDescriptors.size()) {
1106  update_sql += ",";
1107  }
1108  }
1109  update_sql += ";";
1110 
1111  LOG(INFO) << update_sql;
1112 
1114 
1115  // compare source against CTAS
1116  std::string select_sql = "SELECT id";
1117  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1118  select_sql += ", col_dst_" + std::to_string(col);
1119  select_sql += ", col_src_" + std::to_string(col);
1120  }
1121  select_sql += " FROM update_test ORDER BY id;";
1122 
1123  LOG(INFO) << select_sql;
1124  auto select_result = run_multiple_agg(select_sql, ExecutorDeviceType::CPU);
1125 
1126  for (unsigned int row = 0; row < num_rows; row++) {
1127  const auto select_crt_row = select_result->getNextRow(true, false);
1128 
1129  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1130  auto tcd = columnDescriptors[col];
1131 
1132  {
1133  const auto mapd_variant = select_crt_row[(2 * col) + 1];
1134  auto mapd_ti = select_result->getColType((2 * col) + 1);
1135  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
1136  }
1137  {
1138  const auto mapd_variant = select_crt_row[(2 * col) + 2];
1139  auto mapd_ti = select_result->getColType((2 * col) + 2);
1140  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
1141  }
1142  }
1143  }
1144 }
1145 
1147  std::vector<std::shared_ptr<TestColumnDescriptor>>& columnDescriptors,
1148  size_t numColsToUpdate) {
1149  // disable if varlen update is not enabled
1150  if (!is_feature_enabled<VarlenUpdates>()) {
1151  LOG(WARNING) << "skipping...";
1152  return;
1153  }
1154 
1155  run_ddl_statement("DROP TABLE IF EXISTS update_test;");
1156 
1157  std::string create_sql = "CREATE TABLE update_test(id int";
1158  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1159  auto tcd = columnDescriptors[col];
1160 
1161  if (col < numColsToUpdate) {
1162  if (tcd->skip_test("UpdateColumnByLiteral")) {
1163  LOG(ERROR) << "not supported... skipping";
1164  return;
1165  }
1166  }
1167  create_sql += ", col_dst_" + std::to_string(col) + " " + tcd->get_column_definition();
1168  }
1169  create_sql += ") WITH (fragment_size=3);";
1170 
1171  LOG(INFO) << create_sql;
1172 
1173  run_ddl_statement(create_sql);
1174 
1175  size_t num_rows = 10;
1176 
1177  // fill source table
1178  for (unsigned int row = 0; row < num_rows; row++) {
1179  std::string insert_sql = "INSERT INTO update_test VALUES (" + std::to_string(row);
1180  for (unsigned int col = 0; col < numColsToUpdate; col++) {
1181  auto tcd = columnDescriptors[col];
1182  insert_sql += ", " + tcd->get_column_value(row + 1);
1183  }
1184  for (unsigned int col = numColsToUpdate; col < columnDescriptors.size(); col++) {
1185  auto tcd = columnDescriptors[col];
1186  insert_sql += ", " + tcd->get_column_value(row);
1187  }
1188  insert_sql += ");";
1189 
1191  }
1192 
1193  // execute Updates
1194  for (unsigned int row = 0; row < num_rows; row++) {
1195  std::string update_sql = "UPDATE update_test set ";
1196  for (unsigned int col = 0; col < numColsToUpdate; col++) {
1197  auto tcd = columnDescriptors[col];
1198  update_sql +=
1199  " col_dst_" + std::to_string(col) + "=" + tcd->get_update_column_value(row);
1200  if (col + 1 < numColsToUpdate) {
1201  update_sql += ",";
1202  }
1203  }
1204  update_sql += " WHERE id=" + std::to_string(row) + ";";
1205  LOG(INFO) << update_sql;
1207  }
1208 
1209  // compare source against CTAS
1210  std::string select_sql = "SELECT id";
1211  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1212  select_sql += ", col_dst_" + std::to_string(col);
1213  }
1214  select_sql += " FROM update_test ORDER BY id;";
1215 
1216  LOG(INFO) << select_sql;
1217  auto select_result = run_multiple_agg(select_sql, ExecutorDeviceType::CPU);
1218 
1219  for (unsigned int row = 0; row < num_rows; row++) {
1220  const auto select_crt_row = select_result->getNextRow(true, false);
1221 
1222  for (unsigned int col = 0; col < columnDescriptors.size(); col++) {
1223  auto tcd = columnDescriptors[col];
1224 
1225  {
1226  const auto mapd_variant = select_crt_row[(1 * col) + 1];
1227  auto mapd_ti = select_result->getColType((1 * col) + 1);
1228  ASSERT_EQ(true, tcd->check_column_value(row, mapd_ti, &mapd_variant));
1229  }
1230  }
1231  }
1232 }
1233 
1234 TEST_P(Update, UpdateColumnByLiteral) {
1235  updateColumnByLiteralTest(columnDescriptors, columnDescriptors.size());
1236 }
1237 
1238 TEST_P(Update, UpdateFirstColumnByLiteral) {
1239  if (columnDescriptors.size() > 1) {
1240  updateColumnByLiteralTest(columnDescriptors, 1);
1241  }
1242 }
1243 
1244 const std::shared_ptr<TestColumnDescriptor> STRING_NONE_BASE =
1245  std::make_shared<StringColumnDescriptor>("TEXT ENCODING NONE",
1246  kTEXT,
1247  "STRING_NONE_BASE");
1248 
1249 #ifdef RUN_ALL_TEST
1250 
1251 #define INSTANTIATE_DATA_INGESTION_TEST(CDT) \
1252  INSTANTIATE_TEST_CASE_P( \
1253  CDT, \
1254  Ctas, \
1255  testing::Values(std::vector<std::shared_ptr<TestColumnDescriptor>>{CDT})); \
1256  INSTANTIATE_TEST_CASE_P( \
1257  CDT, \
1258  Itas, \
1259  testing::Values(std::vector<std::shared_ptr<TestColumnDescriptor>>{CDT})); \
1260  INSTANTIATE_TEST_CASE_P( \
1261  CDT, \
1262  Update, \
1263  testing::Values(std::vector<std::shared_ptr<TestColumnDescriptor>>{CDT})); \
1264  INSTANTIATE_TEST_CASE_P( \
1265  VARLEN_TEXT_AND_##CDT, \
1266  Update, \
1267  testing::Values( \
1268  std::vector<std::shared_ptr<TestColumnDescriptor>>{STRING_NONE_BASE, CDT})); \
1269  INSTANTIATE_TEST_CASE_P( \
1270  CDT##_AND_VARLEN_TEXT, \
1271  Update, \
1272  testing::Values( \
1273  std::vector<std::shared_ptr<TestColumnDescriptor>>{CDT, STRING_NONE_BASE}))
1274 
1275 #else
1276 
1277 #define INSTANTIATE_DATA_INGESTION_TEST(CDT)
1278 
1279 #endif
1280 
1281 #define BOOLEAN_COLUMN_TEST(name, c_type, definition, sql_type, null) \
1282  const std::shared_ptr<TestColumnDescriptor> name = \
1283  std::make_shared<BooleanColumnDescriptor>(definition, sql_type); \
1284  INSTANTIATE_DATA_INGESTION_TEST(name)
1285 
1286 #define NUMBER_COLUMN_TEST(name, c_type, definition, sql_type, null) \
1287  const std::shared_ptr<TestColumnDescriptor> name = \
1288  std::make_shared<NumberColumnDescriptor<c_type>>(definition, sql_type, null); \
1289  INSTANTIATE_DATA_INGESTION_TEST(name)
1290 
1291 #define STRING_COLUMN_TEST(name, definition, sql_type) \
1292  const std::shared_ptr<TestColumnDescriptor> name = \
1293  std::make_shared<StringColumnDescriptor>(definition, sql_type, #name); \
1294  INSTANTIATE_DATA_INGESTION_TEST(name)
1295 
1296 #define TIME_COLUMN_TEST(name, definition, sql_type, format, offset, scale) \
1297  const std::shared_ptr<TestColumnDescriptor> name = \
1298  std::make_shared<DateTimeColumnDescriptor>( \
1299  definition, sql_type, format, offset, scale); \
1300  INSTANTIATE_DATA_INGESTION_TEST(name)
1301 
1302 #define ARRAY_COLUMN_TEST(name, definition) \
1303  const std::shared_ptr<TestColumnDescriptor> name##_ARRAY = \
1304  std::make_shared<ArrayColumnDescriptor>(definition, name, 0); \
1305  INSTANTIATE_DATA_INGESTION_TEST(name##_ARRAY); \
1306  const std::shared_ptr<TestColumnDescriptor> name##_FIXED_LEN_ARRAY = \
1307  std::make_shared<ArrayColumnDescriptor>(definition, name, 3); \
1308  INSTANTIATE_DATA_INGESTION_TEST(name##_FIXED_LEN_ARRAY)
1309 
1310 BOOLEAN_COLUMN_TEST(BOOLEAN, int64_t, "BOOLEAN", kBOOLEAN, NULL_TINYINT);
1311 ARRAY_COLUMN_TEST(BOOLEAN, "BOOLEAN");
1312 
1313 NUMBER_COLUMN_TEST(TINYINT, int64_t, "TINYINT", kTINYINT, NULL_TINYINT);
1314 ARRAY_COLUMN_TEST(TINYINT, "TINYINT");
1315 
1316 NUMBER_COLUMN_TEST(SMALLINT, int64_t, "SMALLINT", kSMALLINT, NULL_SMALLINT);
1317 NUMBER_COLUMN_TEST(SMALLINT_8,
1318  int64_t,
1319  "SMALLINT ENCODING FIXED(8)",
1320  kSMALLINT,
1321  NULL_SMALLINT);
1322 ARRAY_COLUMN_TEST(SMALLINT, "SMALLINT");
1323 
1324 NUMBER_COLUMN_TEST(INTEGER, int64_t, "INTEGER", kINT, NULL_INT);
1325 NUMBER_COLUMN_TEST(INTEGER_8, int64_t, "INTEGER ENCODING FIXED(8)", kINT, NULL_INT);
1326 NUMBER_COLUMN_TEST(INTEGER_16, int64_t, "INTEGER ENCODING FIXED(16)", kINT, NULL_INT);
1327 ARRAY_COLUMN_TEST(INTEGER, "INTEGER");
1328 
1329 NUMBER_COLUMN_TEST(BIGINT, int64_t, "BIGINT", kBIGINT, NULL_BIGINT);
1330 NUMBER_COLUMN_TEST(BIGINT_8, int64_t, "BIGINT ENCODING FIXED(8)", kBIGINT, NULL_BIGINT);
1331 NUMBER_COLUMN_TEST(BIGINT_16, int64_t, "BIGINT ENCODING FIXED(16)", kBIGINT, NULL_BIGINT);
1332 NUMBER_COLUMN_TEST(BIGINT_32, int64_t, "BIGINT ENCODING FIXED(32)", kBIGINT, NULL_BIGINT);
1333 ARRAY_COLUMN_TEST(BIGINT, "BIGINT");
1334 
1335 NUMBER_COLUMN_TEST(FLOAT, float, "FLOAT", kFLOAT, NULL_FLOAT);
1336 ARRAY_COLUMN_TEST(FLOAT, "FLOAT");
1337 
1338 NUMBER_COLUMN_TEST(DOUBLE, double, "DOUBLE", kDOUBLE, NULL_DOUBLE);
1339 ARRAY_COLUMN_TEST(DOUBLE, "DOUBLE");
1340 
1341 NUMBER_COLUMN_TEST(NUMERIC, int64_t, "NUMERIC(18)", kNUMERIC, NULL_BIGINT);
1342 NUMBER_COLUMN_TEST(NUMERIC_32,
1343  int64_t,
1344  "NUMERIC(9) ENCODING FIXED(32)",
1345  kNUMERIC,
1346  NULL_BIGINT);
1347 NUMBER_COLUMN_TEST(NUMERIC_16,
1348  int64_t,
1349  "NUMERIC(4) ENCODING FIXED(16)",
1350  kNUMERIC,
1351  NULL_BIGINT);
1352 ARRAY_COLUMN_TEST(NUMERIC, "NUMERIC(18)");
1353 
1354 NUMBER_COLUMN_TEST(DECIMAL, int64_t, "DECIMAL(18,9)", kDECIMAL, NULL_BIGINT);
1355 NUMBER_COLUMN_TEST(DECIMAL_32,
1356  int64_t,
1357  "DECIMAL(9,2) ENCODING FIXED(32)",
1358  kDECIMAL,
1359  NULL_BIGINT);
1360 NUMBER_COLUMN_TEST(DECIMAL_16,
1361  int64_t,
1362  "DECIMAL(4,2) ENCODING FIXED(16)",
1363  kDECIMAL,
1364  NULL_BIGINT);
1365 ARRAY_COLUMN_TEST(DECIMAL, "DECIMAL(18,9)");
1366 
1367 STRING_COLUMN_TEST(CHAR, "CHAR(100)", kCHAR);
1368 STRING_COLUMN_TEST(CHAR_DICT, "CHAR(100) ENCODING DICT", kCHAR);
1369 STRING_COLUMN_TEST(CHAR_DICT_8, "CHAR(100) ENCODING DICT(8)", kCHAR);
1370 STRING_COLUMN_TEST(CHAR_DICT_16, "CHAR(100) ENCODING DICT(16)", kCHAR);
1371 STRING_COLUMN_TEST(CHAR_NONE, "CHAR(100) ENCODING NONE", kCHAR);
1372 ARRAY_COLUMN_TEST(CHAR, "CHAR(100)");
1373 
1374 STRING_COLUMN_TEST(VARCHAR, "VARCHAR(100)", kCHAR);
1375 STRING_COLUMN_TEST(VARCHAR_DICT, "VARCHAR(100) ENCODING DICT", kCHAR);
1376 STRING_COLUMN_TEST(VARCHAR_DICT_8, "VARCHAR(100) ENCODING DICT(8)", kCHAR);
1377 STRING_COLUMN_TEST(VARCHAR_DICT_16, "VARCHAR(100) ENCODING DICT(16)", kCHAR);
1378 STRING_COLUMN_TEST(VARCHAR_NONE, "VARCHAR(100) ENCODING NONE", kCHAR);
1379 ARRAY_COLUMN_TEST(VARCHAR, "VARCHAR(100)");
1380 
1381 STRING_COLUMN_TEST(TEXT, "TEXT", kTEXT);
1382 STRING_COLUMN_TEST(TEXT_DICT, "TEXT ENCODING DICT", kTEXT);
1383 STRING_COLUMN_TEST(TEXT_DICT_8, "TEXT ENCODING DICT(8)", kTEXT);
1384 STRING_COLUMN_TEST(TEXT_DICT_16, "TEXT ENCODING DICT(16)", kTEXT);
1385 STRING_COLUMN_TEST(TEXT_NONE, "TEXT ENCODING NONE", kTEXT);
1386 ARRAY_COLUMN_TEST(TEXT, "TEXT");
1387 
1388 TIME_COLUMN_TEST(TIME, "TIME", kTIME, "%T", 0, 1);
1389 TIME_COLUMN_TEST(TIME_32, "TIME ENCODING FIXED(32)", kTIME, "%T", 0, 1);
1390 ARRAY_COLUMN_TEST(TIME, "TIME");
1391 
1392 TIME_COLUMN_TEST(DATE, "DATE", kDATE, "%F", 0, 160 * 60 * 100);
1393 TIME_COLUMN_TEST(DATE_16, "DATE ENCODING FIXED(16)", kDATE, "%F", 0, 160 * 60 * 100);
1394 ARRAY_COLUMN_TEST(DATE, "DATE");
1395 
1396 TIME_COLUMN_TEST(TIMESTAMP, "TIMESTAMP", kTIMESTAMP, "%F %T", 0, 160 * 60 * 100);
1397 TIME_COLUMN_TEST(TIMESTAMP_32,
1398  "TIMESTAMP ENCODING FIXED(32)",
1399  kTIMESTAMP,
1400  "%F %T",
1401  0,
1402  160 * 60 * 100);
1403 ARRAY_COLUMN_TEST(TIMESTAMP, "TIMESTAMP");
1404 
1405 const std::shared_ptr<TestColumnDescriptor> GEO_POINT =
1406  std::shared_ptr<TestColumnDescriptor>(new GeoPointColumnDescriptor(kPOINT));
1408 
1409 const std::shared_ptr<TestColumnDescriptor> GEO_LINESTRING =
1410  std::shared_ptr<TestColumnDescriptor>(new GeoLinestringColumnDescriptor(kLINESTRING));
1412 
1413 const std::shared_ptr<TestColumnDescriptor> GEO_POLYGON =
1414  std::shared_ptr<TestColumnDescriptor>(new GeoPolygonColumnDescriptor(kPOLYGON));
1416 
1417 const std::shared_ptr<TestColumnDescriptor> GEO_MULTI_POLYGON =
1418  std::shared_ptr<TestColumnDescriptor>(
1421 
1422 const std::vector<std::shared_ptr<TestColumnDescriptor>> ALL = {STRING_NONE_BASE,
1423  BOOLEAN,
1424  BOOLEAN_ARRAY,
1425  BOOLEAN_FIXED_LEN_ARRAY,
1426  TINYINT,
1427  TINYINT_ARRAY,
1428  TINYINT_FIXED_LEN_ARRAY,
1429  SMALLINT_8,
1430  SMALLINT,
1431  SMALLINT_ARRAY,
1432  SMALLINT_FIXED_LEN_ARRAY,
1433  INTEGER_8,
1434  INTEGER_16,
1435  INTEGER,
1436  INTEGER_ARRAY,
1437  INTEGER_FIXED_LEN_ARRAY,
1438  BIGINT_8,
1439  BIGINT_16,
1440  BIGINT_32,
1441  BIGINT,
1442  BIGINT_ARRAY,
1443  BIGINT_FIXED_LEN_ARRAY,
1444  FLOAT,
1445  FLOAT_ARRAY,
1446  FLOAT_FIXED_LEN_ARRAY,
1447  DOUBLE,
1448  DOUBLE_ARRAY,
1449  DOUBLE_FIXED_LEN_ARRAY,
1450  NUMERIC_16,
1451  NUMERIC_32,
1452  NUMERIC,
1453  NUMERIC_ARRAY,
1454  NUMERIC_FIXED_LEN_ARRAY,
1455  DECIMAL_16,
1456  DECIMAL_32,
1457  DECIMAL,
1458  DECIMAL_ARRAY,
1459  DECIMAL_FIXED_LEN_ARRAY,
1460  TEXT_NONE,
1461  TEXT_DICT,
1462  TEXT_DICT_8,
1463  TEXT_DICT_16,
1464  TEXT,
1465  TEXT_ARRAY,
1466  TEXT_FIXED_LEN_ARRAY,
1467  TIME_32,
1468  TIME,
1469  TIME_ARRAY,
1470  TIME_FIXED_LEN_ARRAY,
1471  DATE_16,
1472  DATE,
1473  DATE_ARRAY,
1474  DATE_FIXED_LEN_ARRAY,
1475  TIMESTAMP_32,
1476  TIMESTAMP,
1477  TIMESTAMP_ARRAY,
1478  TIMESTAMP_FIXED_LEN_ARRAY,
1479  GEO_POINT,
1481  GEO_POLYGON,
1483 
1484 INSTANTIATE_TEST_CASE_P(MIXED_ALL, Ctas, testing::Values(ALL));
1485 INSTANTIATE_TEST_CASE_P(MIXED_ALL, Itas, testing::Values(ALL));
1486 INSTANTIATE_TEST_CASE_P(MIXED_ALL, Update, testing::Values(ALL));
1487 
1489  MIXED_VARLEN_WITHOUT_GEO,
1490  Update,
1491  testing::Values(std::vector<std::shared_ptr<TestColumnDescriptor>>{
1493  BOOLEAN_ARRAY,
1494  BOOLEAN_FIXED_LEN_ARRAY,
1495  TINYINT_ARRAY,
1496  TINYINT_FIXED_LEN_ARRAY,
1497  SMALLINT_ARRAY,
1498  SMALLINT_FIXED_LEN_ARRAY,
1499  INTEGER_ARRAY,
1500  INTEGER_FIXED_LEN_ARRAY,
1501  BIGINT_ARRAY,
1502  BIGINT_FIXED_LEN_ARRAY,
1503  NUMERIC_ARRAY,
1504  NUMERIC_FIXED_LEN_ARRAY,
1505  TEXT_NONE,
1506  TEXT_ARRAY,
1507  TEXT_FIXED_LEN_ARRAY,
1508  TIME_ARRAY,
1509  TIME_FIXED_LEN_ARRAY,
1510  DATE_ARRAY,
1511  DATE_FIXED_LEN_ARRAY,
1512  TIMESTAMP_ARRAY,
1513  TIMESTAMP_FIXED_LEN_ARRAY
1514 
1515  }));
1516 
1517 int main(int argc, char* argv[]) {
1518  testing::InitGoogleTest(&argc, argv);
1520 
1522 
1523  int err{0};
1524  try {
1525  err = RUN_ALL_TESTS();
1526  } catch (const std::exception& e) {
1527  LOG(ERROR) << e.what();
1528  }
1529  QR::reset();
1530  return err;
1531 }
std::string get_column_definition() override
#define NUMBER_COLUMN_TEST(name, c_type, definition, sql_type, null)
std::string make_column_value(int rows, std::string prefix, std::string suffix)
TEST_P(Ctas, CreateTableAsSelect)
std::string get_column_value(int row) override
#define NULL_DOUBLE
Definition: sqltypes.h:177
std::string getColumnWktStringValue(int row)
const std::shared_ptr< TestColumnDescriptor > GEO_MULTI_POLYGON
const int8_t const int64_t * num_rows
Definition: sqltypes.h:51
SQLTypes
Definition: sqltypes.h:40
ExecutorDeviceType
std::string get_column_definition() override
std::string get_update_column_value(int row) override
#define NULL_BIGINT
Definition: sqltypes.h:175
virtual std::string get_update_column_value(int row)
std::string get_column_definition() override
std::string getColumnWktStringValue(int row)
#define LOG(tag)
Definition: Logger.h:182
std::string get_column_value(int row) override
ArrayColumnDescriptor(std::string def, const std::shared_ptr< TestColumnDescriptor > columnDesc, int fixed_len=0)
#define BASE_PATH
auto sql(const std::string &sql_stmts)
TEST(Ctas, SyntaxCheck)
const std::vector< std::shared_ptr< TestColumnDescriptor > > ALL
HOST DEVICE int get_scale() const
Definition: sqltypes.h:324
bool skip_test(std::string name) override
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:319
#define BOOLEAN_COLUMN_TEST(name, c_type, definition, sql_type, null)
DateTimeColumnDescriptor(std::string col_type, SQLTypes sql_type, std::string fmt, long offset, int scale)
const std::shared_ptr< TestColumnDescriptor > GEO_LINESTRING
bool skip_test(std::string name) override
bool check_column_value(const int row, const SQLTypeInfo &type, const ScalarTargetValue *scalarValue) override
std::string to_string(char const *&&v)
StringColumnDescriptor(std::string col_type, SQLTypes sql_type, std::string pfix)
std::string get_column_definition() override
std::string getColumnWktStringValue(int row)
NumberColumnDescriptor(std::string col_type, SQLTypes sql_type, T null)
static QueryRunner * init(const char *db_path, const std::string &udf_filename="", const size_t max_gpu_mem=0, const int reserved_gpu_mem=256<< 20)
Definition: QueryRunner.h:70
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)
std::string get_column_value(int row) override
void itasTestBody(std::vector< std::shared_ptr< TestColumnDescriptor >> &columnDescriptors, std::string targetPartitionScheme=")")
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
std::string getValueAsString(int row)
virtual std::string get_column_definition()=0
std::string get_column_value(int row) override
bool skip_test(std::string name) override
virtual bool skip_test(std::string name)
std::string get_column_definition() override
#define NULL_TINYINT
Definition: sqltypes.h:172
std::string get_column_definition() override
#define NULL_FLOAT
Definition: sqltypes.h:176
BooleanColumnDescriptor(std::string col_type, SQLTypes sql_type)
#define STRING_COLUMN_TEST(name, definition, sql_type)
bool skip_test(std::string name) override
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
virtual void runDDLStatement(const std::string &)
SQLTypeInfoCore get_elem_type() const
Definition: sqltypes.h:628
#define NULL_INT
Definition: sqltypes.h:174
INSTANTIATE_TEST_CASE_P(MIXED_ALL, Ctas, testing::Values(ALL))
int64_t pow10(int scale)
GeoPointColumnDescriptor(SQLTypes sql_type=kPOINT)
#define ARRAY_COLUMN_TEST(name, definition)
const std::shared_ptr< TestColumnDescriptor > STRING_NONE_BASE
std::shared_ptr< Catalog_Namespace::Catalog > getCatalog() const
#define INSTANTIATE_DATA_INGESTION_TEST(CDT)
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
static QueryRunner * get()
Definition: QueryRunner.h:115
Definition: sqltypes.h:54
Definition: sqltypes.h:55
std::string get_column_definition() override
std::string get_column_definition() override
bool skip_test(std::string name) override
std::string get_column_definition() override
bool skip_test(std::string name) override
#define TIME_COLUMN_TEST(name, definition, sql_type, format, offset, scale)
Definition: sqltypes.h:43
std::string get_column_value(int row) override
virtual std::string get_column_value(int row)=0
virtual bool check_column_value(const int row, const TDatum *datum)=0
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
GeoPolygonColumnDescriptor(SQLTypes sql_type=kPOLYGON)
#define NULL_SMALLINT
Definition: sqltypes.h:173
GeoLinestringColumnDescriptor(SQLTypes sql_type=kLINESTRING)
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
std::string get_column_value(int row) override
int main(int argc, char *argv[])
void init_logger_stderr_only(int argc, char const *const *argv)
Definition: TestHelpers.h:194
bool skip_test(std::string name) override
std::string get_column_value(int row) override
void updateColumnByLiteralTest(std::vector< std::shared_ptr< TestColumnDescriptor >> &columnDescriptors, size_t numColsToUpdate)
const std::shared_ptr< TestColumnDescriptor > GEO_POINT
std::string get_column_value(int row) override
bool skip_test(std::string name) override
std::string getColumnWktStringValue(int row)
boost::variant< ScalarTargetValue, ArrayTargetValue, GeoTargetValue, GeoTargetValuePtr > TargetValue
Definition: TargetValue.h:167
Definition: sqltypes.h:47
bool skip_test(std::string name) override
specifies the content in-memory of a row in the table metadata table
virtual ~TestColumnDescriptor()=default
std::string get_column_value(int row) override
GeoMultiPolygonColumnDescriptor(SQLTypes sql_type=kMULTIPOLYGON)
virtual bool check_column_value(const int row, const SQLTypeInfo &type, const TargetValue *value)
const std::shared_ptr< TestColumnDescriptor > GEO_POLYGON
void run_ddl_statement(std::string ddl)
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
bool check_column_value(int row, const SQLTypeInfo &type, const ScalarTargetValue *value) override
TQueryResult run_multiple_agg(std::string sql)
bool check_column_value(const int row, const SQLTypeInfo &type, const TargetValue *value) override
boost::variant< int64_t, double, float, NullableString > ScalarTargetValue
Definition: TargetValue.h:156