OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Analyzer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, 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 
23 #include "Analyzer.h"
24 #include "Catalog/Catalog.h"
25 #include "Geospatial/Conversion.h"
26 #include "Geospatial/Types.h"
28 #include "RangeTableEntry.h"
29 #include "Shared/DateConverters.h"
30 #include "Shared/misc.h"
31 #include "Shared/sqltypes.h"
32 
33 #include <algorithm>
34 #include <cstring>
35 #include <iostream>
36 #include <stdexcept>
37 
38 namespace Analyzer {
39 
41  if ((type_info.is_string() || type_info.is_geometry()) && !is_null) {
42  delete constval.stringval;
43  }
44 }
45 
47  delete parsetree;
48 }
49 
51  for (auto p : rangetable) {
52  delete p;
53  }
54  delete order_by;
55  delete next_query;
56 }
57 
58 size_t Expr::get_num_column_vars(const bool include_agg) const {
59  std::set<const Analyzer::ColumnVar*,
60  bool (*)(const Analyzer::ColumnVar*, const Analyzer::ColumnVar*)>
62  collect_column_var(colvar_set, include_agg);
63  return colvar_set.size();
64 }
65 
66 std::shared_ptr<Analyzer::Expr> ColumnVar::deep_copy() const {
67  return makeExpr<ColumnVar>(type_info, column_key_, rte_idx_);
68 }
69 
70 void ExpressionTuple::collect_rte_idx(std::set<int>& rte_idx_set) const {
71  for (const auto& column : tuple_) {
72  column->collect_rte_idx(rte_idx_set);
73  }
74 }
75 
76 std::shared_ptr<Analyzer::Expr> ExpressionTuple::deep_copy() const {
77  std::vector<std::shared_ptr<Expr>> tuple_deep_copy;
78  for (const auto& column : tuple_) {
79  const auto column_deep_copy =
80  std::dynamic_pointer_cast<Analyzer::ColumnVar>(column->deep_copy());
81  CHECK(column_deep_copy);
82  tuple_deep_copy.push_back(column_deep_copy);
83  }
84  return makeExpr<ExpressionTuple>(tuple_deep_copy);
85 }
86 
87 std::shared_ptr<Analyzer::Expr> Var::deep_copy() const {
88  return makeExpr<Var>(type_info, column_key_, rte_idx_, which_row, varno);
89 }
90 
91 std::shared_ptr<Analyzer::Expr> Constant::deep_copy() const {
92  Datum d = constval;
93  if ((type_info.is_string() || type_info.is_geometry()) && !is_null) {
94  d.stringval = new std::string(*constval.stringval);
95  }
96  if (type_info.get_type() == kARRAY) {
97  return makeExpr<Constant>(type_info, is_null, value_list);
98  }
99  return makeExpr<Constant>(type_info, is_null, d);
100 }
101 
102 std::shared_ptr<Analyzer::Expr> UOper::deep_copy() const {
103  return makeExpr<UOper>(type_info, contains_agg, optype, operand->deep_copy());
104 }
105 
106 std::shared_ptr<Analyzer::Expr> BinOper::deep_copy() const {
107  return makeExpr<BinOper>(type_info,
108  contains_agg,
109  optype,
110  qualifier,
111  left_operand->deep_copy(),
112  right_operand->deep_copy());
113 }
114 
115 std::shared_ptr<Analyzer::Expr> RangeOper::deep_copy() const {
116  return makeExpr<RangeOper>(left_inclusive_,
118  left_operand_->deep_copy(),
119  right_operand_->deep_copy());
120 }
121 
122 std::shared_ptr<Analyzer::Expr> Subquery::deep_copy() const {
123  // not supported yet.
124  CHECK(false);
125  return nullptr;
126 }
127 
128 std::shared_ptr<Analyzer::Expr> InValues::deep_copy() const {
129  std::list<std::shared_ptr<Analyzer::Expr>> new_value_list;
130  for (auto p : value_list) {
131  new_value_list.push_back(p->deep_copy());
132  }
133  return makeExpr<InValues>(arg->deep_copy(), new_value_list);
134 }
135 
136 std::shared_ptr<Analyzer::Expr> MLPredictExpr::deep_copy() const {
137  std::vector<std::shared_ptr<Analyzer::Expr>> regressors_copy;
138  for (auto r : regressor_values_) {
139  regressors_copy.emplace_back(r->deep_copy());
140  }
141  return makeExpr<MLPredictExpr>(model_value_->deep_copy(), regressors_copy);
142 }
143 
144 std::shared_ptr<Analyzer::Expr> PCAProjectExpr::deep_copy() const {
145  std::vector<std::shared_ptr<Analyzer::Expr>> features_copy;
146  for (auto feature_value : feature_values_) {
147  features_copy.emplace_back(feature_value->deep_copy());
148  }
149  return makeExpr<PCAProjectExpr>(
150  model_value_->deep_copy(), features_copy, pc_dimension_value_->deep_copy());
151 }
152 
153 std::shared_ptr<Analyzer::Expr> CharLengthExpr::deep_copy() const {
154  return makeExpr<CharLengthExpr>(arg->deep_copy(), calc_encoded_length);
155 }
156 
157 std::shared_ptr<Analyzer::Expr> KeyForStringExpr::deep_copy() const {
158  return makeExpr<KeyForStringExpr>(arg->deep_copy());
159 }
160 
161 std::shared_ptr<Analyzer::Expr> SampleRatioExpr::deep_copy() const {
162  return makeExpr<SampleRatioExpr>(arg->deep_copy());
163 }
164 
165 std::shared_ptr<Analyzer::Expr> CardinalityExpr::deep_copy() const {
166  return makeExpr<CardinalityExpr>(arg->deep_copy());
167 }
168 
169 std::shared_ptr<Analyzer::Expr> LikeExpr::deep_copy() const {
170  return makeExpr<LikeExpr>(arg->deep_copy(),
171  like_expr->deep_copy(),
172  escape_expr ? escape_expr->deep_copy() : nullptr,
173  is_ilike,
174  is_simple);
175 }
176 
177 std::shared_ptr<Analyzer::Expr> RegexpExpr::deep_copy() const {
178  return makeExpr<RegexpExpr>(arg->deep_copy(),
179  pattern_expr->deep_copy(),
180  escape_expr ? escape_expr->deep_copy() : nullptr);
181 }
182 
183 std::shared_ptr<Analyzer::Expr> WidthBucketExpr::deep_copy() const {
184  return makeExpr<WidthBucketExpr>(target_value_->deep_copy(),
185  lower_bound_->deep_copy(),
186  upper_bound_->deep_copy(),
187  partition_count_->deep_copy());
188 }
189 
190 std::shared_ptr<Analyzer::Expr> LikelihoodExpr::deep_copy() const {
191  return makeExpr<LikelihoodExpr>(arg->deep_copy(), likelihood);
192 }
193 
194 std::shared_ptr<Analyzer::Expr> AggExpr::deep_copy() const {
195  return makeExpr<AggExpr>(
196  type_info, aggtype, arg ? arg->deep_copy() : nullptr, is_distinct, arg1);
197 }
198 
199 std::shared_ptr<Analyzer::Expr> CaseExpr::deep_copy() const {
200  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
201  new_list;
202  for (auto p : expr_pair_list) {
203  new_list.emplace_back(p.first->deep_copy(), p.second->deep_copy());
204  }
205  return makeExpr<CaseExpr>(type_info,
206  contains_agg,
207  new_list,
208  else_expr == nullptr ? nullptr : else_expr->deep_copy());
209 }
210 
211 std::shared_ptr<Analyzer::Expr> ExtractExpr::deep_copy() const {
212  return makeExpr<ExtractExpr>(type_info, contains_agg, field_, from_expr_->deep_copy());
213 }
214 
215 std::shared_ptr<Analyzer::Expr> DateaddExpr::deep_copy() const {
216  return makeExpr<DateaddExpr>(
217  type_info, field_, number_->deep_copy(), datetime_->deep_copy());
218 }
219 
220 std::shared_ptr<Analyzer::Expr> DatediffExpr::deep_copy() const {
221  return makeExpr<DatediffExpr>(
222  type_info, field_, start_->deep_copy(), end_->deep_copy());
223 }
224 
225 std::shared_ptr<Analyzer::Expr> DatetruncExpr::deep_copy() const {
226  return makeExpr<DatetruncExpr>(
227  type_info, contains_agg, field_, from_expr_->deep_copy());
228 }
229 
230 std::shared_ptr<Analyzer::Expr> OffsetInFragment::deep_copy() const {
231  return makeExpr<OffsetInFragment>();
232 }
233 
234 std::shared_ptr<Analyzer::Expr> WindowFrame::deep_copy() const {
235  return makeExpr<WindowFrame>(bound_type_,
236  bound_expr_ ? bound_expr_->deep_copy() : nullptr);
237 }
238 
239 std::shared_ptr<Analyzer::Expr> WindowFunction::deep_copy() const {
240  return makeExpr<WindowFunction>(type_info,
241  kind_,
242  args_,
244  order_keys_,
246  frame_start_bound_->deep_copy(),
247  frame_end_bound_->deep_copy(),
248  collation_);
249 }
250 
252  return makeExpr<Analyzer::ArrayExpr>(
254 }
255 
256 std::shared_ptr<Analyzer::Expr> GeoUOper::deep_copy() const {
258  return makeExpr<GeoUOper>(op_, type_info, type_info, args0_);
259  }
260  return makeExpr<GeoUOper>(op_, type_info, ti0_, args0_);
261 }
262 
263 std::shared_ptr<Analyzer::Expr> GeoBinOper::deep_copy() const {
264  return makeExpr<GeoBinOper>(op_, type_info, ti0_, ti1_, args0_, args1_);
265 }
266 
268  const SQLTypeInfo& left_type,
269  const SQLTypeInfo& right_type,
270  SQLTypeInfo* new_left_type,
271  SQLTypeInfo* new_right_type) {
272  SQLTypeInfo result_type;
273  SQLTypeInfo common_type;
274  *new_left_type = left_type;
275  *new_right_type = right_type;
276  if (IS_LOGIC(op)) {
277  if (left_type.get_type() != kBOOLEAN || right_type.get_type() != kBOOLEAN) {
278  throw std::runtime_error(
279  "non-boolean operands cannot be used in logic operations.");
280  }
281  result_type = SQLTypeInfo(kBOOLEAN, false);
282  } else if (IS_COMPARISON(op)) {
283  if (left_type != right_type) {
284  if (left_type.is_number() && right_type.is_number()) {
285  common_type = common_numeric_type(left_type, right_type);
286  *new_left_type = common_type;
287  new_left_type->set_notnull(left_type.get_notnull());
288  *new_right_type = common_type;
289  new_right_type->set_notnull(right_type.get_notnull());
290  } else if (left_type.is_time() && right_type.is_time()) {
291  switch (left_type.get_type()) {
292  case kTIMESTAMP:
293  switch (right_type.get_type()) {
294  case kTIME:
295  throw std::runtime_error("Cannont compare between TIMESTAMP and TIME.");
296  break;
297  case kDATE:
298  *new_left_type = SQLTypeInfo(left_type.get_type(),
299  left_type.get_dimension(),
300  0,
301  left_type.get_notnull());
302  *new_right_type = *new_left_type;
303  new_right_type->set_notnull(right_type.get_notnull());
304  break;
305  case kTIMESTAMP:
306  *new_left_type = SQLTypeInfo(
307  kTIMESTAMP,
308  std::max(left_type.get_dimension(), right_type.get_dimension()),
309  0,
310  left_type.get_notnull());
311  *new_right_type = SQLTypeInfo(
312  kTIMESTAMP,
313  std::max(left_type.get_dimension(), right_type.get_dimension()),
314  0,
315  right_type.get_notnull());
316  break;
317  default:
318  CHECK(false);
319  }
320  break;
321  case kTIME:
322  switch (right_type.get_type()) {
323  case kTIMESTAMP:
324  throw std::runtime_error("Cannont compare between TIME and TIMESTAMP.");
325  break;
326  case kDATE:
327  throw std::runtime_error("Cannont compare between TIME and DATE.");
328  break;
329  case kTIME:
330  *new_left_type = SQLTypeInfo(
331  kTIME,
332  std::max(left_type.get_dimension(), right_type.get_dimension()),
333  0,
334  left_type.get_notnull());
335  *new_right_type = SQLTypeInfo(
336  kTIME,
337  std::max(left_type.get_dimension(), right_type.get_dimension()),
338  0,
339  right_type.get_notnull());
340  break;
341  default:
342  CHECK(false);
343  }
344  break;
345  case kDATE:
346  switch (right_type.get_type()) {
347  case kTIMESTAMP:
348  *new_left_type = SQLTypeInfo(right_type.get_type(),
349  right_type.get_dimension(),
350  0,
351  left_type.get_notnull());
352  *new_right_type = *new_left_type;
353  new_right_type->set_notnull(right_type.get_notnull());
354  break;
355  case kDATE:
356  *new_left_type = SQLTypeInfo(left_type.get_type(),
357  left_type.get_dimension(),
358  0,
359  left_type.get_notnull());
360  *new_right_type = *new_left_type;
361  new_right_type->set_notnull(right_type.get_notnull());
362  break;
363  case kTIME:
364  throw std::runtime_error("Cannont compare between DATE and TIME.");
365  break;
366  default:
367  CHECK(false);
368  }
369  break;
370  default:
371  CHECK(false);
372  }
373  } else if (left_type.is_string() && right_type.is_time()) {
374  *new_left_type = right_type;
375  new_left_type->set_notnull(left_type.get_notnull());
376  *new_right_type = right_type;
377  } else if (left_type.is_time() && right_type.is_string()) {
378  *new_left_type = left_type;
379  *new_right_type = left_type;
380  new_right_type->set_notnull(right_type.get_notnull());
381  } else if (left_type.is_string() && right_type.is_string()) {
382  *new_left_type = left_type;
383  *new_right_type = right_type;
384  } else if (left_type.is_boolean() && right_type.is_boolean()) {
385  const bool notnull = left_type.get_notnull() && right_type.get_notnull();
386  common_type = SQLTypeInfo(kBOOLEAN, notnull);
387  *new_left_type = common_type;
388  *new_right_type = common_type;
389  } else {
390  throw std::runtime_error("Cannot compare between " + left_type.get_type_name() +
391  " and " + right_type.get_type_name());
392  }
393  }
394  result_type = SQLTypeInfo(kBOOLEAN, false);
395  } else if (op == kMINUS &&
396  (left_type.get_type() == kDATE || left_type.get_type() == kTIMESTAMP) &&
397  right_type.is_timeinterval()) {
398  *new_left_type = left_type;
399  *new_right_type = right_type;
400  result_type = left_type;
401  } else if (IS_ARITHMETIC(op)) {
402  if (!(left_type.is_number() || left_type.is_timeinterval()) ||
403  !(right_type.is_number() || right_type.is_timeinterval())) {
404  throw std::runtime_error("non-numeric operands in arithmetic operations.");
405  }
406  if (op == kMODULO && (!left_type.is_integer() || !right_type.is_integer())) {
407  throw std::runtime_error("non-integer operands in modulo operation.");
408  }
409  common_type = common_numeric_type(left_type, right_type);
410  if (common_type.is_decimal()) {
411  if (op == kMULTIPLY) {
412  // Decimal multiplication requires common_type adjustment:
413  // dimension and scale of the result should be increased.
414  auto new_dimension = left_type.get_dimension() + right_type.get_dimension();
415  // If new dimension is over 20 digits, the result may overflow, or it may not.
416  // Rely on the runtime overflow detection rather than a static check here.
417  if (common_type.get_dimension() < new_dimension) {
418  common_type.set_dimension(new_dimension);
419  }
420  common_type.set_scale(left_type.get_scale() + right_type.get_scale());
421  } else if (op == kPLUS || op == kMINUS) {
422  // Scale should remain the same but dimension could actually go up
423  common_type.set_dimension(common_type.get_dimension() + 1);
424  }
425  }
426  *new_left_type = common_type;
427  new_left_type->set_notnull(left_type.get_notnull());
428  *new_right_type = common_type;
429  new_right_type->set_notnull(right_type.get_notnull());
430  if (op == kMULTIPLY) {
431  new_left_type->set_scale(left_type.get_scale());
432  new_right_type->set_scale(right_type.get_scale());
433  }
434  result_type = common_type;
435  } else {
436  throw std::runtime_error("invalid binary operator type.");
437  }
438  result_type.set_notnull(left_type.get_notnull() && right_type.get_notnull());
439  return result_type;
440 }
441 
442 namespace {
443 bool has_same_dict(const SQLTypeInfo& type1, const SQLTypeInfo& type2) {
444  const auto& type1_dict_key = type1.getStringDictKey();
445  const auto& type2_dict_key = type2.getStringDictKey();
446  return (type1_dict_key == type2_dict_key ||
447  (type1_dict_key.db_id == type2_dict_key.db_id &&
448  type1_dict_key.dict_id == TRANSIENT_DICT(type2_dict_key.dict_id)));
449 }
450 } // namespace
451 
453  const SQLTypeInfo& type2) {
454  SQLTypeInfo common_type;
456  shared::StringDictKey dict_key;
457  CHECK(type1.is_string() && type2.is_string());
458  // if type1 and type2 have the same DICT encoding then keep it
459  // otherwise, they must be decompressed
460  if (type1.get_compression() == kENCODING_DICT &&
461  type2.get_compression() == kENCODING_DICT) {
462  if (has_same_dict(type1, type2)) {
463  comp = kENCODING_DICT;
464  if (type1.getStringDictKey().dict_id < type2.getStringDictKey().dict_id) {
465  dict_key = type1.getStringDictKey();
466  } else {
467  dict_key = type2.getStringDictKey();
468  }
469  }
470  } else if (type1.get_compression() == kENCODING_DICT &&
471  type2.get_compression() == kENCODING_NONE) {
472  dict_key = type1.getStringDictKey();
473  } else if (type1.get_compression() == kENCODING_NONE &&
474  type2.get_compression() == kENCODING_DICT) {
475  dict_key = type2.getStringDictKey();
476  } else {
477  dict_key.dict_id =
478  std::max(type1.get_comp_param(),
479  type2.get_comp_param()); // preserve previous comp_param if set
480  }
481  const bool notnull = type1.get_notnull() && type2.get_notnull();
482  if (type1.get_type() == kTEXT || type2.get_type() == kTEXT) {
483  common_type = SQLTypeInfo(kTEXT, 0, 0, notnull, comp, dict_key.dict_id, kNULLT);
484  } else {
485  common_type = SQLTypeInfo(kVARCHAR,
486  std::max(type1.get_dimension(), type2.get_dimension()),
487  0,
488  notnull,
489  comp,
490  dict_key.dict_id,
491  kNULLT);
492  }
493 
494  if (common_type.is_dict_encoded_string()) {
495  common_type.setStringDictKey(dict_key);
496  }
497  return common_type;
498 }
499 
501  const SQLTypeInfo& type2) {
502  SQLTypeInfo common_type;
503  const bool notnull = type1.get_notnull() && type2.get_notnull();
504  if (type1.get_type() == type2.get_type()) {
505  CHECK(((type1.is_number() || type1.is_timeinterval()) &&
506  (type2.is_number() || type2.is_timeinterval())) ||
507  (type1.is_boolean() && type2.is_boolean()));
508  common_type = SQLTypeInfo(type1.get_type(),
509  std::max(type1.get_dimension(), type2.get_dimension()),
510  std::max(type1.get_scale(), type2.get_scale()),
511  notnull);
512  return common_type;
513  }
514  std::string timeinterval_op_error{
515  "Operator type not supported for time interval arithmetic: "};
516  if (type1.is_timeinterval()) {
517  if (!type2.is_number()) {
518  // allow `number` types to interpret millisecond / microsecond / nanosecond b/c it
519  // may require double and decimal types to represent their time value correctly
520  throw std::runtime_error(timeinterval_op_error + type2.get_type_name());
521  }
522  return type1;
523  }
524  if (type2.is_timeinterval()) {
525  if (!type1.is_number()) {
526  throw std::runtime_error(timeinterval_op_error + type1.get_type_name());
527  }
528  return type2;
529  }
530  CHECK(type1.is_number() && type2.is_number());
531  switch (type1.get_type()) {
532  case kTINYINT:
533  switch (type2.get_type()) {
534  case kSMALLINT:
535  common_type = SQLTypeInfo(kSMALLINT, notnull);
536  break;
537  case kINT:
538  common_type = SQLTypeInfo(kINT, notnull);
539  break;
540  case kBIGINT:
541  common_type = SQLTypeInfo(kBIGINT, notnull);
542  break;
543  case kFLOAT:
544  common_type = SQLTypeInfo(kFLOAT, notnull);
545  break;
546  case kDOUBLE:
547  common_type = SQLTypeInfo(kDOUBLE, notnull);
548  break;
549  case kNUMERIC:
550  case kDECIMAL:
551  common_type =
553  std::max(5 + type2.get_scale(), type2.get_dimension()),
554  type2.get_scale(),
555  notnull);
556  break;
557  default:
558  CHECK(false);
559  }
560  break;
561  case kSMALLINT:
562  switch (type2.get_type()) {
563  case kTINYINT:
564  common_type = SQLTypeInfo(kSMALLINT, notnull);
565  break;
566  case kINT:
567  common_type = SQLTypeInfo(kINT, notnull);
568  break;
569  case kBIGINT:
570  common_type = SQLTypeInfo(kBIGINT, notnull);
571  break;
572  case kFLOAT:
573  common_type = SQLTypeInfo(kFLOAT, notnull);
574  break;
575  case kDOUBLE:
576  common_type = SQLTypeInfo(kDOUBLE, notnull);
577  break;
578  case kNUMERIC:
579  case kDECIMAL:
580  common_type =
582  std::max(5 + type2.get_scale(), type2.get_dimension()),
583  type2.get_scale(),
584  notnull);
585  break;
586  default:
587  CHECK(false);
588  }
589  break;
590  case kINT:
591  switch (type2.get_type()) {
592  case kTINYINT:
593  common_type = SQLTypeInfo(kINT, notnull);
594  break;
595  case kSMALLINT:
596  common_type = SQLTypeInfo(kINT, notnull);
597  break;
598  case kBIGINT:
599  common_type = SQLTypeInfo(kBIGINT, notnull);
600  break;
601  case kFLOAT:
602  common_type = SQLTypeInfo(kFLOAT, notnull);
603  break;
604  case kDOUBLE:
605  common_type = SQLTypeInfo(kDOUBLE, notnull);
606  break;
607  case kNUMERIC:
608  case kDECIMAL:
609  common_type = SQLTypeInfo(
610  kDECIMAL,
612  10 + type2.get_scale()),
613  type2.get_dimension()),
614  type2.get_scale(),
615  notnull);
616  break;
617  default:
618  CHECK(false);
619  }
620  break;
621  case kBIGINT:
622  switch (type2.get_type()) {
623  case kTINYINT:
624  common_type = SQLTypeInfo(kBIGINT, notnull);
625  break;
626  case kSMALLINT:
627  common_type = SQLTypeInfo(kBIGINT, notnull);
628  break;
629  case kINT:
630  common_type = SQLTypeInfo(kBIGINT, notnull);
631  break;
632  case kFLOAT:
633  common_type = SQLTypeInfo(kFLOAT, notnull);
634  break;
635  case kDOUBLE:
636  common_type = SQLTypeInfo(kDOUBLE, notnull);
637  break;
638  case kNUMERIC:
639  case kDECIMAL:
640  common_type = SQLTypeInfo(kDECIMAL,
642  type2.get_scale(),
643  notnull);
644  break;
645  default:
646  CHECK(false);
647  }
648  break;
649  case kFLOAT:
650  switch (type2.get_type()) {
651  case kTINYINT:
652  common_type = SQLTypeInfo(kFLOAT, notnull);
653  break;
654  case kSMALLINT:
655  common_type = SQLTypeInfo(kFLOAT, notnull);
656  break;
657  case kINT:
658  common_type = SQLTypeInfo(kFLOAT, notnull);
659  break;
660  case kBIGINT:
661  common_type = SQLTypeInfo(kFLOAT, notnull);
662  break;
663  case kDOUBLE:
664  common_type = SQLTypeInfo(kDOUBLE, notnull);
665  break;
666  case kNUMERIC:
667  case kDECIMAL:
668  common_type = SQLTypeInfo(kFLOAT, notnull);
669  break;
670  default:
671  CHECK(false);
672  }
673  break;
674  case kDOUBLE:
675  switch (type2.get_type()) {
676  case kTINYINT:
677  case kSMALLINT:
678  case kINT:
679  case kBIGINT:
680  case kFLOAT:
681  case kNUMERIC:
682  case kDECIMAL:
683  common_type = SQLTypeInfo(kDOUBLE, notnull);
684  break;
685  default:
686  CHECK(false);
687  }
688  break;
689  case kNUMERIC:
690  case kDECIMAL:
691  switch (type2.get_type()) {
692  case kTINYINT:
693  common_type =
695  std::max(3 + type1.get_scale(), type1.get_dimension()),
696  type1.get_scale(),
697  notnull);
698  break;
699  case kSMALLINT:
700  common_type =
702  std::max(5 + type1.get_scale(), type1.get_dimension()),
703  type1.get_scale(),
704  notnull);
705  break;
706  case kINT:
707  common_type = SQLTypeInfo(
708  kDECIMAL,
710  10 + type1.get_scale()),
711  type2.get_dimension()),
712  type1.get_scale(),
713  notnull);
714  break;
715  case kBIGINT:
716  common_type = SQLTypeInfo(kDECIMAL,
718  type1.get_scale(),
719  notnull);
720  break;
721  case kFLOAT:
722  common_type = SQLTypeInfo(kFLOAT, notnull);
723  break;
724  case kDOUBLE:
725  common_type = SQLTypeInfo(kDOUBLE, notnull);
726  break;
727  case kNUMERIC:
728  case kDECIMAL: {
729  int common_scale = std::max(type1.get_scale(), type2.get_scale());
730  common_type = SQLTypeInfo(kDECIMAL,
731  std::max(type1.get_dimension() - type1.get_scale(),
732  type2.get_dimension() - type2.get_scale()) +
733  common_scale,
734  common_scale,
735  notnull);
736  break;
737  }
738  default:
739  CHECK(false);
740  }
741  break;
742  default:
743  CHECK(false);
744  }
745  common_type.set_fixed_size();
746  return common_type;
747 }
748 
749 std::shared_ptr<Analyzer::Expr> Expr::decompress() {
751  return shared_from_this();
752  }
753  SQLTypeInfo new_type_info(type_info.get_type(),
758  0,
760  return makeExpr<UOper>(new_type_info, contains_agg, kCAST, shared_from_this());
761 }
762 
763 namespace {
765  sql_type_info_copy.set_type(kTEXT);
766  sql_type_info_copy.set_compression(kENCODING_DICT);
767  sql_type_info_copy.set_comp_param(TRANSIENT_DICT_ID);
769  sql_type_info_copy.set_fixed_size();
770  return sql_type_info_copy;
771 }
772 } // namespace
773 
774 std::shared_ptr<Analyzer::Expr> Expr::add_cast(const SQLTypeInfo& new_type_info) {
775  if (new_type_info == type_info) {
776  return shared_from_this();
777  }
778  if (new_type_info.is_string() && type_info.is_string() &&
779  new_type_info.get_compression() == kENCODING_DICT &&
781  has_same_dict(new_type_info, type_info)) {
782  return shared_from_this();
783  }
784  if (!type_info.is_castable(new_type_info)) {
785  if (type_info.is_string() && (new_type_info.is_number() || new_type_info.is_time())) {
786  throw std::runtime_error("Cannot CAST from " + type_info.get_type_name() + " to " +
787  new_type_info.get_type_name() +
788  ". Consider using TRY_CAST instead.");
789  }
790  throw std::runtime_error("Cannot CAST from " + type_info.get_type_name() + " to " +
791  new_type_info.get_type_name());
792  }
793  // @TODO(wei) temporary restriction until executor can support this.
794  const bool has_non_literal_operands = get_num_column_vars(true) > 0UL;
795  if (has_non_literal_operands && new_type_info.is_string() &&
796  new_type_info.get_compression() == kENCODING_DICT &&
797  new_type_info.getStringDictKey().dict_id <= TRANSIENT_DICT_ID) {
799  throw std::runtime_error(
800  "Implicit casts of TEXT ENCODING NONE to TEXT ENCODED DICT are not allowed "
801  "for non-literal arguments. Consider adding an explicit conversion to a "
802  "dictionary-encoded text type with ENCODE_TEXT(<none-encoded text arg>).");
803  }
804  throw std::runtime_error(
805  "Internal error: Cannot apply transient dictionary encoding "
806  "to non-literal expression.");
807  }
808  if (!type_info.is_string() && new_type_info.is_string() &&
809  !new_type_info.is_text_encoding_dict()) {
810  return makeExpr<UOper>(
811  make_transient_dict_type(new_type_info), contains_agg, kCAST, shared_from_this());
812  }
813  return makeExpr<UOper>(new_type_info, contains_agg, kCAST, shared_from_this());
814 }
815 
816 namespace {
817 
818 // Return dec * 10^-scale
819 template <typename T>
820 T floatFromDecimal(int64_t const dec, unsigned const scale) {
821  static_assert(std::is_floating_point_v<T>);
822  return static_cast<T>(dec) / shared::power10(scale);
823 }
824 
825 // Q: Why is there a maxRound() but no minRound()?
826 // A: The numerical value of std::numeric_limits<int64_t>::min() is unchanged when cast
827 // to either float or double, but std::numeric_limits<intXX_t>::max() is incremented to
828 // 2^(XX-1) when cast to float/double for XX in {32,64}, which is an invalid intXX_t
829 // value. Thus the maximum float/double that can be cast to a valid integer type must be
830 // calculated directly, and not just compared to std::numeric_limits<intXX_t>::max().
831 template <typename FLOAT_TYPE, typename INT_TYPE>
832 constexpr FLOAT_TYPE maxRound() {
833  static_assert(std::is_integral_v<INT_TYPE> && std::is_floating_point_v<FLOAT_TYPE>);
834  constexpr int dd =
835  std::numeric_limits<INT_TYPE>::digits - std::numeric_limits<FLOAT_TYPE>::digits;
836  if constexpr (0 < dd) { // NOLINT
837  return static_cast<FLOAT_TYPE>(std::numeric_limits<INT_TYPE>::max() - (1ll << dd));
838  } else {
839  return static_cast<FLOAT_TYPE>(std::numeric_limits<INT_TYPE>::max());
840  }
841 }
842 
843 template <typename TO, typename FROM>
844 TO safeNarrow(FROM const from) {
845  static_assert(std::is_integral_v<TO> && std::is_integral_v<FROM>);
846  static_assert(sizeof(TO) < sizeof(FROM));
847  if (from < static_cast<FROM>(std::numeric_limits<TO>::min()) ||
848  static_cast<FROM>(std::numeric_limits<TO>::max()) < from) {
849  throw std::runtime_error("Overflow or underflow");
850  }
851  return static_cast<TO>(from);
852 }
853 
854 template <typename T>
855 T roundDecimal(int64_t n, unsigned scale) {
856  static_assert(std::is_integral_v<T>);
857  constexpr size_t max_scale = std::numeric_limits<uint64_t>::digits10; // 19
858  constexpr auto pow10 = shared::powersOf<uint64_t, max_scale + 1>(10);
859  if (scale == 0) {
860  if constexpr (sizeof(T) < sizeof(int64_t)) { // NOLINT
861  return safeNarrow<T>(n);
862  } else {
863  return n;
864  }
865  } else if (max_scale < scale) {
866  return 0; // 0.09223372036854775807 rounds to 0
867  }
868  uint64_t const u = std::abs(n);
869  uint64_t const pow = pow10[scale];
870  uint64_t div = u / pow;
871  uint64_t rem = u % pow;
872  div += pow / 2 <= rem;
873  if constexpr (sizeof(T) < sizeof(int64_t)) { // NOLINT
874  return safeNarrow<T>(static_cast<int64_t>(n < 0 ? -div : div));
875  } else {
876  return n < 0 ? -div : div;
877  }
878 }
879 
880 template <typename TO, typename FROM>
881 TO safeRound(FROM const from) {
882  static_assert(std::is_integral_v<TO> && std::is_floating_point_v<FROM>);
883  constexpr FROM max_float = maxRound<FROM, TO>();
884  FROM const n = std::round(from);
885  if (n < static_cast<FROM>(std::numeric_limits<TO>::min()) || max_float < n) {
886  throw std::runtime_error("Overflow or underflow");
887  }
888  return static_cast<TO>(n);
889 }
890 
891 // Return numeric/decimal representation of from with given scale.
892 template <typename T>
893 int64_t safeScale(T from, unsigned const scale) {
894  static_assert(std::is_arithmetic_v<T>);
895  constexpr size_t max_scale = std::numeric_limits<int64_t>::digits10; // 18
896  constexpr auto pow10 = shared::powersOf<int64_t, max_scale + 1>(10);
897  if constexpr (std::is_integral_v<T>) { // NOLINT
898  int64_t retval;
899  if (scale < pow10.size()) {
900 #ifdef __linux__
901  if (!__builtin_mul_overflow(from, pow10[scale], &retval)) {
902  return retval;
903  }
904  // Not over flow safe.
905 #else
906  return from * pow10[scale];
907 #endif
908  }
909  } else if constexpr (std::is_floating_point_v<T>) {
910  if (scale < pow10.size()) {
911  return safeRound<int64_t>(from * pow10[scale]);
912  }
913  }
914  if (from == 0) {
915  return 0;
916  }
917  throw std::runtime_error("Overflow or underflow");
918 }
919 
920 } // namespace
921 
922 void Constant::cast_number(const SQLTypeInfo& new_type_info) {
923  switch (type_info.get_type()) {
924  case kTINYINT:
925  switch (new_type_info.get_type()) {
926  case kTINYINT:
927  break;
928  case kINT:
929  constval.intval = (int32_t)constval.tinyintval;
930  break;
931  case kSMALLINT:
933  break;
934  case kBIGINT:
935  case kTIMESTAMP:
937  break;
938  case kDOUBLE:
940  break;
941  case kFLOAT:
943  break;
944  case kNUMERIC:
945  case kDECIMAL:
947  break;
948  default:
949  CHECK(false);
950  }
951  break;
952  case kINT:
953  switch (new_type_info.get_type()) {
954  case kTINYINT:
955  constval.tinyintval = safeNarrow<int8_t>(constval.intval);
956  break;
957  case kINT:
958  break;
959  case kSMALLINT:
960  constval.smallintval = safeNarrow<int16_t>(constval.intval);
961  break;
962  case kBIGINT:
963  case kTIMESTAMP:
964  constval.bigintval = (int64_t)constval.intval;
965  break;
966  case kDOUBLE:
967  constval.doubleval = (double)constval.intval;
968  break;
969  case kFLOAT:
970  constval.floatval = (float)constval.intval;
971  break;
972  case kNUMERIC:
973  case kDECIMAL:
974  constval.bigintval = safeScale(constval.intval, new_type_info.get_scale());
975  break;
976  default:
977  CHECK(false);
978  }
979  break;
980  case kSMALLINT:
981  switch (new_type_info.get_type()) {
982  case kTINYINT:
983  constval.tinyintval = safeNarrow<int8_t>(constval.smallintval);
984  break;
985  case kINT:
986  constval.intval = (int32_t)constval.smallintval;
987  break;
988  case kSMALLINT:
989  break;
990  case kBIGINT:
991  case kTIMESTAMP:
993  break;
994  case kDOUBLE:
996  break;
997  case kFLOAT:
999  break;
1000  case kNUMERIC:
1001  case kDECIMAL:
1003  break;
1004  default:
1005  CHECK(false);
1006  }
1007  break;
1008  case kBIGINT:
1009  switch (new_type_info.get_type()) {
1010  case kTINYINT:
1011  constval.tinyintval = safeNarrow<int8_t>(constval.bigintval);
1012  break;
1013  case kINT:
1014  constval.intval = safeNarrow<int32_t>(constval.bigintval);
1015  break;
1016  case kSMALLINT:
1017  constval.smallintval = safeNarrow<int16_t>(constval.bigintval);
1018  break;
1019  case kBIGINT:
1020  case kTIMESTAMP:
1021  break;
1022  case kDOUBLE:
1024  break;
1025  case kFLOAT:
1027  break;
1028  case kNUMERIC:
1029  case kDECIMAL:
1031  break;
1032  default:
1033  CHECK(false);
1034  }
1035  break;
1036  case kDOUBLE:
1037  switch (new_type_info.get_type()) {
1038  case kTINYINT:
1039  constval.tinyintval = safeRound<int8_t>(constval.doubleval);
1040  break;
1041  case kINT:
1042  constval.intval = safeRound<int32_t>(constval.doubleval);
1043  break;
1044  case kSMALLINT:
1045  constval.smallintval = safeRound<int16_t>(constval.doubleval);
1046  break;
1047  case kBIGINT:
1048  case kTIMESTAMP:
1049  constval.bigintval = safeRound<int64_t>(constval.doubleval);
1050  break;
1051  case kDOUBLE:
1052  break;
1053  case kFLOAT:
1055  break;
1056  case kNUMERIC:
1057  case kDECIMAL:
1059  break;
1060  default:
1061  CHECK(false);
1062  }
1063  break;
1064  case kFLOAT:
1065  switch (new_type_info.get_type()) {
1066  case kTINYINT:
1067  constval.tinyintval = safeRound<int8_t>(constval.floatval);
1068  break;
1069  case kINT:
1070  constval.intval = safeRound<int32_t>(constval.floatval);
1071  break;
1072  case kSMALLINT:
1073  constval.smallintval = safeRound<int16_t>(constval.floatval);
1074  break;
1075  case kBIGINT:
1076  case kTIMESTAMP:
1077  constval.bigintval = safeRound<int64_t>(constval.floatval);
1078  break;
1079  case kDOUBLE:
1080  constval.doubleval = (double)constval.floatval;
1081  break;
1082  case kFLOAT:
1083  break;
1084  case kNUMERIC:
1085  case kDECIMAL:
1086  constval.bigintval = safeScale(constval.floatval, new_type_info.get_scale());
1087  break;
1088  default:
1089  CHECK(false);
1090  }
1091  break;
1092  case kNUMERIC:
1093  case kDECIMAL:
1094  switch (new_type_info.get_type()) {
1095  case kTINYINT:
1097  roundDecimal<int8_t>(constval.bigintval, type_info.get_scale());
1098  break;
1099  case kINT:
1100  constval.intval =
1101  roundDecimal<int32_t>(constval.bigintval, type_info.get_scale());
1102  break;
1103  case kSMALLINT:
1105  roundDecimal<int16_t>(constval.bigintval, type_info.get_scale());
1106  break;
1107  case kBIGINT:
1108  case kTIMESTAMP:
1110  roundDecimal<int64_t>(constval.bigintval, type_info.get_scale());
1111  break;
1112  case kDOUBLE:
1114  floatFromDecimal<double>(constval.bigintval, type_info.get_scale());
1115  break;
1116  case kFLOAT:
1117  constval.floatval =
1118  floatFromDecimal<float>(constval.bigintval, type_info.get_scale());
1119  break;
1120  case kNUMERIC:
1121  case kDECIMAL:
1123  constval.bigintval, type_info, new_type_info);
1124  break;
1125  default:
1126  CHECK(false);
1127  }
1128  break;
1129  case kTIMESTAMP:
1130  switch (new_type_info.get_type()) {
1131  case kTINYINT:
1132  constval.tinyintval = safeNarrow<int8_t>(constval.bigintval);
1133  break;
1134  case kINT:
1135  constval.intval = safeNarrow<int32_t>(constval.bigintval);
1136  break;
1137  case kSMALLINT:
1138  constval.smallintval = safeNarrow<int16_t>(constval.bigintval);
1139  break;
1140  case kBIGINT:
1141  case kTIMESTAMP:
1142  break;
1143  case kDOUBLE:
1144  constval.doubleval = static_cast<double>(constval.bigintval);
1145  break;
1146  case kFLOAT:
1147  constval.floatval = static_cast<float>(constval.bigintval);
1148  break;
1149  case kNUMERIC:
1150  case kDECIMAL:
1151  for (int i = 0; i < new_type_info.get_scale(); i++) {
1152  constval.bigintval *= 10;
1153  }
1154  break;
1155  default:
1156  CHECK(false);
1157  }
1158  break;
1159  case kBOOLEAN:
1160  switch (new_type_info.get_type()) {
1161  case kTINYINT:
1162  constval.tinyintval = constval.boolval ? 1 : 0;
1163  break;
1164  case kINT:
1165  constval.intval = constval.boolval ? 1 : 0;
1166  break;
1167  case kSMALLINT:
1169  break;
1170  case kBIGINT:
1171  case kTIMESTAMP:
1172  constval.bigintval = constval.boolval ? 1 : 0;
1173  break;
1174  case kDOUBLE:
1175  constval.doubleval = constval.boolval ? 1 : 0;
1176  break;
1177  case kFLOAT:
1178  constval.floatval = constval.boolval ? 1 : 0;
1179  break;
1180  case kNUMERIC:
1181  case kDECIMAL:
1182  constval.bigintval = constval.boolval ? 1 : 0;
1183  for (int i = 0; i < new_type_info.get_scale(); i++) {
1184  constval.bigintval *= 10;
1185  }
1186  break;
1187  default:
1188  CHECK(false);
1189  }
1190  break;
1191  default:
1192  CHECK(false);
1193  }
1194  type_info = new_type_info;
1195 }
1196 
1197 void Constant::cast_string(const SQLTypeInfo& new_type_info) {
1198  std::string* s = constval.stringval;
1199  if (s != nullptr && new_type_info.get_type() != kTEXT &&
1200  static_cast<size_t>(new_type_info.get_dimension()) < s->length()) {
1201  // truncate string
1202  constval.stringval = new std::string(s->substr(0, new_type_info.get_dimension()));
1203  delete s;
1204  }
1205  type_info = new_type_info;
1206 }
1207 
1208 void Constant::cast_from_string(const SQLTypeInfo& new_type_info) {
1209  std::string* s = constval.stringval;
1210  SQLTypeInfo ti = new_type_info;
1211  constval = StringToDatum(*s, ti);
1212  delete s;
1213  type_info = new_type_info;
1214 }
1215 
1216 void Constant::cast_to_string(const SQLTypeInfo& str_type_info) {
1217  const auto str_val = DatumToString(constval, type_info);
1218  constval.stringval = new std::string(str_val);
1219  if (str_type_info.get_type() != kTEXT &&
1220  constval.stringval->length() > static_cast<size_t>(str_type_info.get_dimension())) {
1221  // truncate the string
1222  *constval.stringval = constval.stringval->substr(0, str_type_info.get_dimension());
1223  }
1224  type_info = str_type_info;
1225 }
1226 
1227 namespace {
1228 
1229 // TODO(adb): we should revisit this, as one could argue a Datum should never contain
1230 // a null sentinel. In fact, if we bundle Datum with a null boolean ("NullableDatum"),
1231 // the logic becomes more explicit. There are likely other bugs associated with the
1232 // current logic -- for example, boolean is set to -128 which is likely UB
1233 inline bool is_null_value(const SQLTypeInfo& ti, const Datum& constval) {
1234  switch (ti.get_type()) {
1235  case kBOOLEAN:
1236  return constval.tinyintval == NULL_BOOLEAN;
1237  case kTINYINT:
1238  return constval.tinyintval == NULL_TINYINT;
1239  case kINT:
1240  return constval.intval == NULL_INT;
1241  case kSMALLINT:
1242  return constval.smallintval == NULL_SMALLINT;
1243  case kBIGINT:
1244  case kNUMERIC:
1245  case kDECIMAL:
1246  return constval.bigintval == NULL_BIGINT;
1247  case kTIME:
1248  case kTIMESTAMP:
1249  case kDATE:
1250  case kINTERVAL_DAY_TIME:
1251  case kINTERVAL_YEAR_MONTH:
1252  return constval.bigintval == NULL_BIGINT;
1253  case kVARCHAR:
1254  case kCHAR:
1255  case kTEXT:
1256  return constval.stringval == nullptr;
1257  case kPOINT:
1258  case kMULTIPOINT:
1259  case kLINESTRING:
1260  case kMULTILINESTRING:
1261  case kPOLYGON:
1262  case kMULTIPOLYGON:
1263  return constval.stringval == nullptr;
1264  case kFLOAT:
1265  return constval.floatval == NULL_FLOAT;
1266  case kDOUBLE:
1267  return constval.doubleval == NULL_DOUBLE;
1268  case kNULLT:
1269  return constval.bigintval == 0;
1270  case kARRAY:
1271  return constval.arrayval == nullptr;
1272  default:
1273  UNREACHABLE();
1274  }
1275  UNREACHABLE();
1276  return false;
1277 }
1278 
1279 } // namespace
1280 
1281 void Constant::do_cast(const SQLTypeInfo& new_type_info) {
1282  if (type_info == new_type_info) {
1283  return;
1284  }
1285  if (is_null && !new_type_info.get_notnull()) {
1286  type_info = new_type_info;
1287  set_null_value();
1288  return;
1289  }
1290  if ((new_type_info.is_number() || new_type_info.get_type() == kTIMESTAMP) &&
1291  (new_type_info.get_type() != kTIMESTAMP || type_info.get_type() != kTIMESTAMP) &&
1293  type_info.get_type() == kBOOLEAN)) {
1294  cast_number(new_type_info);
1295  } else if (new_type_info.is_geometry() && type_info.is_string()) {
1296  type_info = new_type_info;
1297  } else if (new_type_info.is_geometry() &&
1298  type_info.get_type() == new_type_info.get_type()) {
1299  type_info = new_type_info;
1300  } else if (new_type_info.is_boolean() && type_info.is_boolean()) {
1301  type_info = new_type_info;
1302  } else if (new_type_info.is_string() && type_info.is_string()) {
1303  cast_string(new_type_info);
1304  } else if (type_info.is_string() || type_info.get_type() == kVARCHAR) {
1305  cast_from_string(new_type_info);
1306  } else if (new_type_info.is_string()) {
1307  cast_to_string(new_type_info);
1308  } else if (new_type_info.get_type() == kDATE && type_info.get_type() == kDATE) {
1309  type_info = new_type_info;
1310  } else if (new_type_info.get_type() == kDATE && type_info.get_type() == kTIMESTAMP) {
1317  type_info = new_type_info;
1318  } else if ((type_info.get_type() == kTIMESTAMP || type_info.get_type() == kDATE) &&
1319  new_type_info.get_type() == kTIMESTAMP) {
1320  const auto dimen = (type_info.get_type() == kDATE) ? 0 : type_info.get_dimension();
1321  if (dimen != new_type_info.get_dimension()) {
1322  constval.bigintval = dimen < new_type_info.get_dimension()
1326  new_type_info.get_dimension() - dimen)
1330  dimen - new_type_info.get_dimension());
1331  }
1332  type_info = new_type_info;
1333  } else if (new_type_info.is_array() && type_info.is_array()) {
1334  auto new_sub_ti = new_type_info.get_elem_type();
1335  for (auto& v : value_list) {
1336  auto c = std::dynamic_pointer_cast<Analyzer::Constant>(v);
1337  if (!c) {
1338  throw std::runtime_error("Invalid array cast.");
1339  }
1340  c->do_cast(new_sub_ti);
1341  }
1342  type_info = new_type_info;
1343  } else if (get_is_null() && (new_type_info.is_number() || new_type_info.is_time() ||
1344  new_type_info.is_string() || new_type_info.is_boolean())) {
1345  type_info = new_type_info;
1346  set_null_value();
1347  } else if (!is_null_value(type_info, constval) &&
1348  get_nullable_type_info(type_info) == new_type_info) {
1349  CHECK(!is_null);
1350  // relax nullability
1351  type_info = new_type_info;
1352  return;
1353  } else if (type_info.is_timestamp() && new_type_info.is_any<kTIME>()) {
1354  type_info = new_type_info;
1355  return;
1356  } else {
1357  throw std::runtime_error("Cast from " + type_info.get_type_name() + " to " +
1358  new_type_info.get_type_name() + " not supported");
1359  }
1360 }
1361 
1363  switch (type_info.get_type()) {
1364  case kBOOLEAN:
1366  break;
1367  case kTINYINT:
1369  break;
1370  case kINT:
1372  break;
1373  case kSMALLINT:
1375  break;
1376  case kBIGINT:
1377  case kNUMERIC:
1378  case kDECIMAL:
1380  break;
1381  case kTIME:
1382  case kTIMESTAMP:
1383  case kDATE:
1385  break;
1386  case kVARCHAR:
1387  case kCHAR:
1388  case kTEXT:
1389  constval.stringval = nullptr;
1390  break;
1391  case kPOINT:
1392  case kMULTIPOINT:
1393  case kLINESTRING:
1394  case kMULTILINESTRING:
1395  case kPOLYGON:
1396  case kMULTIPOLYGON:
1397  constval.stringval = nullptr;
1398  break;
1399  case kFLOAT:
1401  break;
1402  case kDOUBLE:
1404  break;
1405  case kNULLT:
1406  constval.bigintval = 0;
1407  break;
1408  case kARRAY:
1409  constval.arrayval = nullptr;
1410  break;
1411  default:
1412  CHECK(false);
1413  }
1414 }
1415 
1416 std::shared_ptr<Analyzer::Expr> Constant::add_cast(const SQLTypeInfo& new_type_info) {
1417  if (is_null) {
1418  type_info = new_type_info;
1419  set_null_value();
1420  return shared_from_this();
1421  }
1422  if (new_type_info.get_compression() != type_info.get_compression()) {
1423  if (new_type_info.get_compression() != kENCODING_NONE) {
1424  SQLTypeInfo new_ti = new_type_info;
1425  if (new_ti.get_compression() != kENCODING_DATE_IN_DAYS) {
1427  }
1428  do_cast(new_ti);
1429  }
1430  return Expr::add_cast(new_type_info);
1431  }
1432  const auto is_integral_type =
1433  new_type_info.is_integer() || new_type_info.is_decimal() || new_type_info.is_fp();
1434  if (is_integral_type && (type_info.is_time() || type_info.is_date())) {
1435  // Let the codegen phase deal with casts from date/time to a number.
1436  return makeExpr<UOper>(new_type_info, contains_agg, kCAST, shared_from_this());
1437  }
1438  do_cast(new_type_info);
1439  return shared_from_this();
1440 }
1441 
1442 std::shared_ptr<Analyzer::Expr> UOper::add_cast(const SQLTypeInfo& new_type_info) {
1443  if (optype != kCAST) {
1444  return Expr::add_cast(new_type_info);
1445  }
1446  if (type_info.is_string() && new_type_info.is_string() &&
1447  new_type_info.get_compression() == kENCODING_DICT &&
1449  const SQLTypeInfo oti = operand->get_type_info();
1450  if (oti.is_string() && oti.get_compression() == kENCODING_DICT &&
1451  has_same_dict(oti, new_type_info)) {
1452  auto result = operand;
1453  operand = nullptr;
1454  return result;
1455  }
1456  }
1457  return Expr::add_cast(new_type_info);
1458 }
1459 
1460 std::shared_ptr<Analyzer::Expr> CaseExpr::add_cast(const SQLTypeInfo& new_type_info) {
1461  SQLTypeInfo ti = new_type_info;
1462  if (new_type_info.is_string() && new_type_info.get_compression() == kENCODING_DICT &&
1463  new_type_info.getStringDictKey().isTransientDict() && type_info.is_string() &&
1467  auto dict_key = type_info.getStringDictKey();
1468  dict_key.dict_id = TRANSIENT_DICT(dict_key.dict_id);
1469  ti.setStringDictKey(dict_key);
1470  }
1471 
1472  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1473  new_expr_pair_list;
1474  for (auto& p : expr_pair_list) {
1475  new_expr_pair_list.emplace_back(
1476  std::make_pair(p.first, p.second->deep_copy()->add_cast(ti)));
1477  }
1478 
1479  if (else_expr != nullptr) {
1480  else_expr = else_expr->add_cast(ti);
1481  }
1482  // Replace the current WHEN THEN pair list once we are sure all casts have succeeded
1483  expr_pair_list = new_expr_pair_list;
1484 
1485  type_info = ti;
1486  return shared_from_this();
1487 }
1488 
1489 std::shared_ptr<Analyzer::Expr> Subquery::add_cast(const SQLTypeInfo& new_type_info) {
1490  // not supported yet.
1491  CHECK(false);
1492  return nullptr;
1493 }
1494 
1495 int Query::get_rte_idx(const std::string& name) const {
1496  int rte_idx = 0;
1497  for (auto rte : rangetable) {
1498  if (rte->get_rangevar() == name) {
1499  return rte_idx;
1500  }
1501  rte_idx++;
1502  }
1503  return -1;
1504 }
1505 
1507  rangetable.push_back(rte);
1508 }
1509 
1511  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
1512  if (!groupby.empty()) {
1513  for (auto e : groupby) {
1514  auto c = std::dynamic_pointer_cast<ColumnVar>(e);
1515  if (c && column_key_ == c->getColumnKey()) {
1516  return;
1517  }
1518  }
1519  }
1520  throw std::runtime_error(
1521  "expressions in the SELECT or HAVING clause must be an aggregate function or an "
1522  "expression "
1523  "over GROUP BY columns.");
1524 }
1525 
1527  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
1528  if (which_row != kGROUPBY) {
1529  throw std::runtime_error("Internal error: invalid VAR in GROUP BY or HAVING.");
1530  }
1531 }
1532 
1534  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
1535  operand->check_group_by(groupby);
1536 }
1537 
1539  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
1540  left_operand->check_group_by(groupby);
1541  right_operand->check_group_by(groupby);
1542 }
1543 
1544 namespace {
1545 
1546 template <class T>
1547 bool expr_is(const std::shared_ptr<Analyzer::Expr>& expr) {
1548  return std::dynamic_pointer_cast<T>(expr) != nullptr;
1549 }
1550 
1551 } // namespace
1552 
1554  const std::shared_ptr<Analyzer::Expr> cast_operand,
1555  const std::shared_ptr<Analyzer::Expr> const_operand) {
1556  if (expr_is<UOper>(cast_operand) && expr_is<Constant>(const_operand)) {
1557  auto u_expr = std::dynamic_pointer_cast<UOper>(cast_operand);
1558  if (u_expr->get_optype() != kCAST) {
1559  return false;
1560  }
1561  if (!(expr_is<Analyzer::ColumnVar>(u_expr->get_own_operand()) &&
1562  !expr_is<Analyzer::Var>(u_expr->get_own_operand()))) {
1563  return false;
1564  }
1565  const auto& ti = u_expr->get_type_info();
1566  if (ti.is_time() && u_expr->get_operand()->get_type_info().is_time()) {
1567  // Allow casts between time types to pass through
1568  return true;
1569  } else if (ti.is_integer() && u_expr->get_operand()->get_type_info().is_integer()) {
1570  // Allow casts between integer types to pass through
1571  return true;
1572  }
1573  }
1574  return false;
1575 }
1576 
1577 std::shared_ptr<Analyzer::Expr> BinOper::normalize_simple_predicate(int& rte_idx) const {
1578  rte_idx = -1;
1579  if (!IS_COMPARISON(optype) || qualifier != kONE) {
1580  return nullptr;
1581  }
1582  if (expr_is<UOper>(left_operand)) {
1584  auto uo = std::dynamic_pointer_cast<UOper>(left_operand);
1585  auto cv = std::dynamic_pointer_cast<ColumnVar>(uo->get_own_operand());
1586  rte_idx = cv->get_rte_idx();
1587  return this->deep_copy();
1588  }
1589  } else if (expr_is<UOper>(right_operand)) {
1591  auto uo = std::dynamic_pointer_cast<UOper>(right_operand);
1592  auto cv = std::dynamic_pointer_cast<ColumnVar>(uo->get_own_operand());
1593  rte_idx = cv->get_rte_idx();
1594  return makeExpr<BinOper>(type_info,
1595  contains_agg,
1597  qualifier,
1598  right_operand->deep_copy(),
1599  left_operand->deep_copy());
1600  }
1601  } else if (expr_is<ColumnVar>(left_operand) && !expr_is<Var>(left_operand) &&
1602  expr_is<Constant>(right_operand)) {
1603  auto cv = std::dynamic_pointer_cast<ColumnVar>(left_operand);
1604  rte_idx = cv->get_rte_idx();
1605  return this->deep_copy();
1606  } else if (expr_is<Constant>(left_operand) && expr_is<ColumnVar>(right_operand) &&
1607  !expr_is<Var>(right_operand)) {
1608  auto cv = std::dynamic_pointer_cast<ColumnVar>(right_operand);
1609  rte_idx = cv->get_rte_idx();
1610  return makeExpr<BinOper>(type_info,
1611  contains_agg,
1613  qualifier,
1614  right_operand->deep_copy(),
1615  left_operand->deep_copy());
1616  }
1617  return nullptr;
1618 }
1619 
1620 void ColumnVar::group_predicates(std::list<const Expr*>& scan_predicates,
1621  std::list<const Expr*>& join_predicates,
1622  std::list<const Expr*>& const_predicates) const {
1623  if (type_info.get_type() == kBOOLEAN) {
1624  scan_predicates.push_back(this);
1625  }
1626 }
1627 
1628 void UOper::group_predicates(std::list<const Expr*>& scan_predicates,
1629  std::list<const Expr*>& join_predicates,
1630  std::list<const Expr*>& const_predicates) const {
1631  std::set<int> rte_idx_set;
1632  operand->collect_rte_idx(rte_idx_set);
1633  if (rte_idx_set.size() > 1) {
1634  join_predicates.push_back(this);
1635  } else if (rte_idx_set.size() == 1) {
1636  scan_predicates.push_back(this);
1637  } else {
1638  const_predicates.push_back(this);
1639  }
1640 }
1641 
1642 void BinOper::group_predicates(std::list<const Expr*>& scan_predicates,
1643  std::list<const Expr*>& join_predicates,
1644  std::list<const Expr*>& const_predicates) const {
1645  if (optype == kAND) {
1646  left_operand->group_predicates(scan_predicates, join_predicates, const_predicates);
1647  right_operand->group_predicates(scan_predicates, join_predicates, const_predicates);
1648  return;
1649  }
1650  std::set<int> rte_idx_set;
1651  left_operand->collect_rte_idx(rte_idx_set);
1652  right_operand->collect_rte_idx(rte_idx_set);
1653  if (rte_idx_set.size() > 1) {
1654  join_predicates.push_back(this);
1655  } else if (rte_idx_set.size() == 1) {
1656  scan_predicates.push_back(this);
1657  } else {
1658  const_predicates.push_back(this);
1659  }
1660 }
1661 
1662 namespace {
1663 
1665  const auto const_expr = dynamic_cast<const Analyzer::Constant*>(expr);
1666  if (const_expr) {
1667  return const_expr->get_is_null();
1668  }
1669  const auto& expr_ti = expr->get_type_info();
1670  return !expr_ti.get_notnull();
1671 }
1672 
1673 bool is_in_values_nullable(const std::shared_ptr<Analyzer::Expr>& a,
1674  const std::list<std::shared_ptr<Analyzer::Expr>>& l) {
1675  if (is_expr_nullable(a.get())) {
1676  return true;
1677  }
1678  for (const auto& v : l) {
1679  if (is_expr_nullable(v.get())) {
1680  return true;
1681  }
1682  }
1683  return false;
1684 }
1685 
1686 } // namespace
1687 
1688 InValues::InValues(std::shared_ptr<Analyzer::Expr> a,
1689  const std::list<std::shared_ptr<Analyzer::Expr>>& l)
1690  : Expr(kBOOLEAN, !is_in_values_nullable(a, l)), arg(a), value_list(l) {}
1691 
1692 void InValues::group_predicates(std::list<const Expr*>& scan_predicates,
1693  std::list<const Expr*>& join_predicates,
1694  std::list<const Expr*>& const_predicates) const {
1695  std::set<int> rte_idx_set;
1696  arg->collect_rte_idx(rte_idx_set);
1697  if (rte_idx_set.size() > 1) {
1698  join_predicates.push_back(this);
1699  } else if (rte_idx_set.size() == 1) {
1700  scan_predicates.push_back(this);
1701  } else {
1702  const_predicates.push_back(this);
1703  }
1704 }
1705 
1706 InIntegerSet::InIntegerSet(const std::shared_ptr<const Analyzer::Expr> a,
1707  const std::vector<int64_t>& l,
1708  const bool not_null)
1709  : Expr(kBOOLEAN, not_null), arg(a), value_list(l) {}
1710 
1711 void CharLengthExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1712  std::list<const Expr*>& join_predicates,
1713  std::list<const Expr*>& const_predicates) const {
1714  std::set<int> rte_idx_set;
1715  arg->collect_rte_idx(rte_idx_set);
1716  if (rte_idx_set.size() > 1) {
1717  join_predicates.push_back(this);
1718  } else if (rte_idx_set.size() == 1) {
1719  scan_predicates.push_back(this);
1720  } else {
1721  const_predicates.push_back(this);
1722  }
1723 }
1724 
1725 void KeyForStringExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1726  std::list<const Expr*>& join_predicates,
1727  std::list<const Expr*>& const_predicates) const {
1728  std::set<int> rte_idx_set;
1729  arg->collect_rte_idx(rte_idx_set);
1730  if (rte_idx_set.size() > 1) {
1731  join_predicates.push_back(this);
1732  } else if (rte_idx_set.size() == 1) {
1733  scan_predicates.push_back(this);
1734  } else {
1735  const_predicates.push_back(this);
1736  }
1737 }
1738 
1739 void MLPredictExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1740  std::list<const Expr*>& join_predicates,
1741  std::list<const Expr*>& const_predicates) const {
1742  std::set<int> rte_idx_set;
1743  for (const auto& regressor_value : regressor_values_) {
1744  regressor_value->collect_rte_idx(rte_idx_set);
1745  }
1746  if (rte_idx_set.size() > 1) {
1747  join_predicates.push_back(this);
1748  } else if (rte_idx_set.size() == 1) {
1749  scan_predicates.push_back(this);
1750  } else {
1751  const_predicates.push_back(this);
1752  }
1753 }
1754 
1755 void PCAProjectExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1756  std::list<const Expr*>& join_predicates,
1757  std::list<const Expr*>& const_predicates) const {
1758  std::set<int> rte_idx_set;
1759  for (const auto& feature_value : feature_values_) {
1760  feature_value->collect_rte_idx(rte_idx_set);
1761  }
1762  if (rte_idx_set.size() > 1) {
1763  join_predicates.push_back(this);
1764  } else if (rte_idx_set.size() == 1) {
1765  scan_predicates.push_back(this);
1766  } else {
1767  const_predicates.push_back(this);
1768  }
1769 }
1770 
1771 void SampleRatioExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1772  std::list<const Expr*>& join_predicates,
1773  std::list<const Expr*>& const_predicates) const {
1774  std::set<int> rte_idx_set;
1775  arg->collect_rte_idx(rte_idx_set);
1776  if (rte_idx_set.size() > 1) {
1777  join_predicates.push_back(this);
1778  } else if (rte_idx_set.size() == 1) {
1779  scan_predicates.push_back(this);
1780  } else {
1781  const_predicates.push_back(this);
1782  }
1783 }
1784 
1785 void StringOper::group_predicates(std::list<const Expr*>& scan_predicates,
1786  std::list<const Expr*>& join_predicates,
1787  std::list<const Expr*>& const_predicates) const {
1788  std::set<int> rte_idx_set;
1789  for (const auto& arg : args_) {
1790  arg->collect_rte_idx(rte_idx_set);
1791  }
1792  if (rte_idx_set.size() > 1) {
1793  join_predicates.push_back(this);
1794  } else if (rte_idx_set.size() == 1) {
1795  scan_predicates.push_back(this);
1796  } else {
1797  const_predicates.push_back(this);
1798  }
1799 }
1800 
1801 void CardinalityExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1802  std::list<const Expr*>& join_predicates,
1803  std::list<const Expr*>& const_predicates) const {
1804  std::set<int> rte_idx_set;
1805  arg->collect_rte_idx(rte_idx_set);
1806  if (rte_idx_set.size() > 1) {
1807  join_predicates.push_back(this);
1808  } else if (rte_idx_set.size() == 1) {
1809  scan_predicates.push_back(this);
1810  } else {
1811  const_predicates.push_back(this);
1812  }
1813 }
1814 
1815 void LikeExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1816  std::list<const Expr*>& join_predicates,
1817  std::list<const Expr*>& const_predicates) const {
1818  std::set<int> rte_idx_set;
1819  arg->collect_rte_idx(rte_idx_set);
1820  if (rte_idx_set.size() > 1) {
1821  join_predicates.push_back(this);
1822  } else if (rte_idx_set.size() == 1) {
1823  scan_predicates.push_back(this);
1824  } else {
1825  const_predicates.push_back(this);
1826  }
1827 }
1828 
1829 void RegexpExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1830  std::list<const Expr*>& join_predicates,
1831  std::list<const Expr*>& const_predicates) const {
1832  std::set<int> rte_idx_set;
1833  arg->collect_rte_idx(rte_idx_set);
1834  if (rte_idx_set.size() > 1) {
1835  join_predicates.push_back(this);
1836  } else if (rte_idx_set.size() == 1) {
1837  scan_predicates.push_back(this);
1838  } else {
1839  const_predicates.push_back(this);
1840  }
1841 }
1842 
1843 void WidthBucketExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1844  std::list<const Expr*>& join_predicates,
1845  std::list<const Expr*>& const_predicates) const {
1846  std::set<int> rte_idx_set;
1847  target_value_->collect_rte_idx(rte_idx_set);
1848  if (rte_idx_set.size() > 1) {
1849  join_predicates.push_back(this);
1850  } else if (rte_idx_set.size() == 1) {
1851  scan_predicates.push_back(this);
1852  } else {
1853  const_predicates.push_back(this);
1854  }
1855 }
1856 
1857 void LikelihoodExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1858  std::list<const Expr*>& join_predicates,
1859  std::list<const Expr*>& const_predicates) const {
1860  std::set<int> rte_idx_set;
1861  arg->collect_rte_idx(rte_idx_set);
1862  if (rte_idx_set.size() > 1) {
1863  join_predicates.push_back(this);
1864  } else if (rte_idx_set.size() == 1) {
1865  scan_predicates.push_back(this);
1866  } else {
1867  const_predicates.push_back(this);
1868  }
1869 }
1870 
1871 void AggExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1872  std::list<const Expr*>& join_predicates,
1873  std::list<const Expr*>& const_predicates) const {
1874  std::set<int> rte_idx_set;
1875  arg->collect_rte_idx(rte_idx_set);
1876  if (rte_idx_set.size() > 1) {
1877  join_predicates.push_back(this);
1878  } else if (rte_idx_set.size() == 1) {
1879  scan_predicates.push_back(this);
1880  } else {
1881  const_predicates.push_back(this);
1882  }
1883 }
1884 
1885 void CaseExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1886  std::list<const Expr*>& join_predicates,
1887  std::list<const Expr*>& const_predicates) const {
1888  std::set<int> rte_idx_set;
1889  for (auto p : expr_pair_list) {
1890  p.first->collect_rte_idx(rte_idx_set);
1891  p.second->collect_rte_idx(rte_idx_set);
1892  }
1893  if (else_expr != nullptr) {
1894  else_expr->collect_rte_idx(rte_idx_set);
1895  }
1896  if (rte_idx_set.size() > 1) {
1897  join_predicates.push_back(this);
1898  } else if (rte_idx_set.size() == 1) {
1899  scan_predicates.push_back(this);
1900  } else {
1901  const_predicates.push_back(this);
1902  }
1903 }
1904 
1905 void ExtractExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1906  std::list<const Expr*>& join_predicates,
1907  std::list<const Expr*>& const_predicates) const {
1908  std::set<int> rte_idx_set;
1909  from_expr_->collect_rte_idx(rte_idx_set);
1910  if (rte_idx_set.size() > 1) {
1911  join_predicates.push_back(this);
1912  } else if (rte_idx_set.size() == 1) {
1913  scan_predicates.push_back(this);
1914  } else {
1915  const_predicates.push_back(this);
1916  }
1917 }
1918 
1919 void DateaddExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1920  std::list<const Expr*>& join_predicates,
1921  std::list<const Expr*>& const_predicates) const {
1922  std::set<int> rte_idx_set;
1923  number_->collect_rte_idx(rte_idx_set);
1924  datetime_->collect_rte_idx(rte_idx_set);
1925  if (rte_idx_set.size() > 1) {
1926  join_predicates.push_back(this);
1927  } else if (rte_idx_set.size() == 1) {
1928  scan_predicates.push_back(this);
1929  } else {
1930  const_predicates.push_back(this);
1931  }
1932 }
1933 
1934 void DatediffExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1935  std::list<const Expr*>& join_predicates,
1936  std::list<const Expr*>& const_predicates) const {
1937  std::set<int> rte_idx_set;
1938  start_->collect_rte_idx(rte_idx_set);
1939  end_->collect_rte_idx(rte_idx_set);
1940  if (rte_idx_set.size() > 1) {
1941  join_predicates.push_back(this);
1942  } else if (rte_idx_set.size() == 1) {
1943  scan_predicates.push_back(this);
1944  } else {
1945  const_predicates.push_back(this);
1946  }
1947 }
1948 
1949 void DatetruncExpr::group_predicates(std::list<const Expr*>& scan_predicates,
1950  std::list<const Expr*>& join_predicates,
1951  std::list<const Expr*>& const_predicates) const {
1952  std::set<int> rte_idx_set;
1953  from_expr_->collect_rte_idx(rte_idx_set);
1954  if (rte_idx_set.size() > 1) {
1955  join_predicates.push_back(this);
1956  } else if (rte_idx_set.size() == 1) {
1957  scan_predicates.push_back(this);
1958  } else {
1959  const_predicates.push_back(this);
1960  }
1961 }
1962 
1963 std::shared_ptr<Analyzer::Expr> ColumnVar::rewrite_with_targetlist(
1964  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
1965  for (auto tle : tlist) {
1966  const Expr* e = tle->get_expr();
1967  const ColumnVar* colvar = dynamic_cast<const ColumnVar*>(e);
1968  if (colvar != nullptr) {
1969  if (column_key_ == colvar->getColumnKey()) {
1970  return colvar->deep_copy();
1971  }
1972  }
1973  }
1974  throw std::runtime_error("Internal error: cannot find ColumnVar in targetlist.");
1975 }
1976 
1977 std::shared_ptr<Analyzer::Expr> ColumnVar::rewrite_with_child_targetlist(
1978  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
1979  int varno = 1;
1980  for (auto tle : tlist) {
1981  const Expr* e = tle->get_expr();
1982  const ColumnVar* colvar = dynamic_cast<const ColumnVar*>(e);
1983  if (colvar == nullptr) {
1984  throw std::runtime_error(
1985  "Internal Error: targetlist in rewrite_with_child_targetlist is not all "
1986  "columns.");
1987  }
1988  if (column_key_ == colvar->getColumnKey()) {
1989  return makeExpr<Var>(colvar->get_type_info(),
1990  colvar->getColumnKey(),
1991  colvar->get_rte_idx(),
1993  varno);
1994  }
1995  varno++;
1996  }
1997  throw std::runtime_error("Internal error: cannot find ColumnVar in child targetlist.");
1998 }
1999 
2000 std::shared_ptr<Analyzer::Expr> ColumnVar::rewrite_agg_to_var(
2001  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2002  int varno = 1;
2003  for (auto tle : tlist) {
2004  const Expr* e = tle->get_expr();
2005  if (typeid(*e) != typeid(AggExpr)) {
2006  const ColumnVar* colvar = dynamic_cast<const ColumnVar*>(e);
2007  if (colvar == nullptr) {
2008  throw std::runtime_error(
2009  "Internal Error: targetlist in rewrite_agg_to_var is not all columns and "
2010  "aggregates.");
2011  }
2012  if (column_key_ == colvar->getColumnKey()) {
2013  return makeExpr<Var>(colvar->get_type_info(),
2014  colvar->getColumnKey(),
2015  colvar->get_rte_idx(),
2017  varno);
2018  }
2019  }
2020  varno++;
2021  }
2022  throw std::runtime_error(
2023  "Internal error: cannot find ColumnVar from having clause in targetlist.");
2024 }
2025 
2026 std::shared_ptr<Analyzer::Expr> Var::rewrite_agg_to_var(
2027  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2028  int varno = 1;
2029  for (auto tle : tlist) {
2030  const Expr* e = tle->get_expr();
2031  if (*e == *this) {
2032  return makeExpr<Var>(e->get_type_info(), Var::kINPUT_OUTER, varno);
2033  }
2034  varno++;
2035  }
2036  throw std::runtime_error(
2037  "Internal error: cannot find Var from having clause in targetlist.");
2038 }
2039 
2040 std::shared_ptr<Analyzer::Expr> StringOper::rewrite_with_targetlist(
2041  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2042  std::vector<std::shared_ptr<Analyzer::Expr>> rewritten_args;
2043  for (const auto& arg : args_) {
2044  rewritten_args.emplace_back(arg->rewrite_with_targetlist(tlist));
2045  }
2046  return makeExpr<StringOper>(kind_, rewritten_args);
2047 }
2048 
2049 std::shared_ptr<Analyzer::Expr> StringOper::rewrite_with_child_targetlist(
2050  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2051  std::vector<std::shared_ptr<Analyzer::Expr>> rewritten_args;
2052  for (const auto& arg : args_) {
2053  rewritten_args.emplace_back(arg->rewrite_with_child_targetlist(tlist));
2054  }
2055  return makeExpr<StringOper>(kind_, rewritten_args);
2056 }
2057 
2058 std::shared_ptr<Analyzer::Expr> StringOper::rewrite_agg_to_var(
2059  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2060  std::vector<std::shared_ptr<Analyzer::Expr>> rewritten_args;
2061  for (const auto& arg : args_) {
2062  rewritten_args.emplace_back(arg->rewrite_agg_to_var(tlist));
2063  }
2064  return makeExpr<StringOper>(kind_, rewritten_args);
2065 }
2066 
2067 std::shared_ptr<Analyzer::Expr> InValues::rewrite_with_targetlist(
2068  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2069  std::list<std::shared_ptr<Analyzer::Expr>> new_value_list;
2070  for (auto v : value_list) {
2071  new_value_list.push_back(v->deep_copy());
2072  }
2073  return makeExpr<InValues>(arg->rewrite_with_targetlist(tlist), new_value_list);
2074 }
2075 
2076 std::shared_ptr<Analyzer::Expr> InValues::rewrite_with_child_targetlist(
2077  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2078  std::list<std::shared_ptr<Analyzer::Expr>> new_value_list;
2079  for (auto v : value_list) {
2080  new_value_list.push_back(v->deep_copy());
2081  }
2082  return makeExpr<InValues>(arg->rewrite_with_child_targetlist(tlist), new_value_list);
2083 }
2084 
2085 std::shared_ptr<Analyzer::Expr> InValues::rewrite_agg_to_var(
2086  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2087  std::list<std::shared_ptr<Analyzer::Expr>> new_value_list;
2088  for (auto v : value_list) {
2089  new_value_list.push_back(v->rewrite_agg_to_var(tlist));
2090  }
2091  return makeExpr<InValues>(arg->rewrite_agg_to_var(tlist), new_value_list);
2092 }
2093 
2094 std::shared_ptr<Analyzer::Expr> AggExpr::rewrite_with_targetlist(
2095  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2096  for (auto tle : tlist) {
2097  const Expr* e = tle->get_expr();
2098  if (typeid(*e) == typeid(AggExpr)) {
2099  const AggExpr* agg = dynamic_cast<const AggExpr*>(e);
2100  if (*this == *agg) {
2101  return agg->deep_copy();
2102  }
2103  }
2104  }
2105  throw std::runtime_error("Internal error: cannot find AggExpr in targetlist.");
2106 }
2107 
2108 std::shared_ptr<Analyzer::Expr> AggExpr::rewrite_with_child_targetlist(
2109  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2110  return makeExpr<AggExpr>(type_info,
2111  aggtype,
2112  arg ? arg->rewrite_with_child_targetlist(tlist) : nullptr,
2113  is_distinct,
2114  arg1);
2115 }
2116 
2117 std::shared_ptr<Analyzer::Expr> AggExpr::rewrite_agg_to_var(
2118  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2119  int varno = 1;
2120  for (auto tle : tlist) {
2121  const Expr* e = tle->get_expr();
2122  if (typeid(*e) == typeid(AggExpr)) {
2123  const AggExpr* agg_expr = dynamic_cast<const AggExpr*>(e);
2124  if (*this == *agg_expr) {
2125  return makeExpr<Var>(agg_expr->get_type_info(), Var::kINPUT_OUTER, varno);
2126  }
2127  }
2128  varno++;
2129  }
2130  throw std::runtime_error(
2131  "Internal error: cannot find AggExpr from having clause in targetlist.");
2132 }
2133 
2134 std::shared_ptr<Analyzer::Expr> CaseExpr::rewrite_with_targetlist(
2135  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2136  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
2137  epair_list;
2138  for (auto p : expr_pair_list) {
2139  epair_list.emplace_back(p.first->rewrite_with_targetlist(tlist),
2140  p.second->rewrite_with_targetlist(tlist));
2141  }
2142  return makeExpr<CaseExpr>(
2143  type_info,
2144  contains_agg,
2145  epair_list,
2146  else_expr ? else_expr->rewrite_with_targetlist(tlist) : nullptr);
2147 }
2148 
2149 std::shared_ptr<Analyzer::Expr> ExtractExpr::rewrite_with_targetlist(
2150  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2151  return makeExpr<ExtractExpr>(
2152  type_info, contains_agg, field_, from_expr_->rewrite_with_targetlist(tlist));
2153 }
2154 
2155 std::shared_ptr<Analyzer::Expr> DateaddExpr::rewrite_with_targetlist(
2156  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2157  return makeExpr<DateaddExpr>(type_info,
2158  field_,
2159  number_->rewrite_with_targetlist(tlist),
2160  datetime_->rewrite_with_targetlist(tlist));
2161 }
2162 
2163 std::shared_ptr<Analyzer::Expr> DatediffExpr::rewrite_with_targetlist(
2164  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2165  return makeExpr<DatediffExpr>(type_info,
2166  field_,
2167  start_->rewrite_with_targetlist(tlist),
2168  end_->rewrite_with_targetlist(tlist));
2169 }
2170 
2171 std::shared_ptr<Analyzer::Expr> DatetruncExpr::rewrite_with_targetlist(
2172  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2173  return makeExpr<DatetruncExpr>(
2174  type_info, contains_agg, field_, from_expr_->rewrite_with_targetlist(tlist));
2175 }
2176 
2177 std::shared_ptr<Analyzer::Expr> CaseExpr::rewrite_with_child_targetlist(
2178  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2179  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
2180  epair_list;
2181  for (auto p : expr_pair_list) {
2182  epair_list.emplace_back(p.first->rewrite_with_child_targetlist(tlist),
2183  p.second->rewrite_with_child_targetlist(tlist));
2184  }
2185  return makeExpr<CaseExpr>(
2186  type_info,
2187  contains_agg,
2188  epair_list,
2189  else_expr ? else_expr->rewrite_with_child_targetlist(tlist) : nullptr);
2190 }
2191 
2192 std::shared_ptr<Analyzer::Expr> ExtractExpr::rewrite_with_child_targetlist(
2193  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2194  return makeExpr<ExtractExpr>(
2195  type_info, contains_agg, field_, from_expr_->rewrite_with_child_targetlist(tlist));
2196 }
2197 
2198 std::shared_ptr<Analyzer::Expr> DateaddExpr::rewrite_with_child_targetlist(
2199  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2200  return makeExpr<DateaddExpr>(type_info,
2201  field_,
2202  number_->rewrite_with_child_targetlist(tlist),
2203  datetime_->rewrite_with_child_targetlist(tlist));
2204 }
2205 
2206 std::shared_ptr<Analyzer::Expr> DatediffExpr::rewrite_with_child_targetlist(
2207  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2208  return makeExpr<DatediffExpr>(type_info,
2209  field_,
2210  start_->rewrite_with_child_targetlist(tlist),
2211  end_->rewrite_with_child_targetlist(tlist));
2212 }
2213 
2214 std::shared_ptr<Analyzer::Expr> DatetruncExpr::rewrite_with_child_targetlist(
2215  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2216  return makeExpr<DatetruncExpr>(
2217  type_info, contains_agg, field_, from_expr_->rewrite_with_child_targetlist(tlist));
2218 }
2219 
2220 std::shared_ptr<Analyzer::Expr> CaseExpr::rewrite_agg_to_var(
2221  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2222  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
2223  epair_list;
2224  for (auto p : expr_pair_list) {
2225  epair_list.emplace_back(p.first->rewrite_agg_to_var(tlist),
2226  p.second->rewrite_agg_to_var(tlist));
2227  }
2228  return makeExpr<CaseExpr>(type_info,
2229  contains_agg,
2230  epair_list,
2231  else_expr ? else_expr->rewrite_agg_to_var(tlist) : nullptr);
2232 }
2233 
2234 std::shared_ptr<Analyzer::Expr> ExtractExpr::rewrite_agg_to_var(
2235  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2236  return makeExpr<ExtractExpr>(
2237  type_info, contains_agg, field_, from_expr_->rewrite_agg_to_var(tlist));
2238 }
2239 
2240 std::shared_ptr<Analyzer::Expr> DateaddExpr::rewrite_agg_to_var(
2241  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2242  return makeExpr<DateaddExpr>(type_info,
2243  field_,
2244  number_->rewrite_agg_to_var(tlist),
2245  datetime_->rewrite_agg_to_var(tlist));
2246 }
2247 
2248 std::shared_ptr<Analyzer::Expr> DatediffExpr::rewrite_agg_to_var(
2249  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2250  return makeExpr<DatediffExpr>(type_info,
2251  field_,
2252  start_->rewrite_agg_to_var(tlist),
2253  end_->rewrite_agg_to_var(tlist));
2254 }
2255 
2256 std::shared_ptr<Analyzer::Expr> DatetruncExpr::rewrite_agg_to_var(
2257  const std::vector<std::shared_ptr<TargetEntry>>& tlist) const {
2258  return makeExpr<DatetruncExpr>(
2259  type_info, contains_agg, field_, from_expr_->rewrite_agg_to_var(tlist));
2260 }
2261 
2262 bool ColumnVar::operator==(const Expr& rhs) const {
2263  if (typeid(rhs) != typeid(ColumnVar) && typeid(rhs) != typeid(Var)) {
2264  return false;
2265  }
2266  const ColumnVar& rhs_cv = dynamic_cast<const ColumnVar&>(rhs);
2267  if (rte_idx_ != -1) {
2268  return (column_key_ == rhs_cv.getColumnKey()) && (rte_idx_ == rhs_cv.get_rte_idx());
2269  }
2270  const Var* v = dynamic_cast<const Var*>(this);
2271  if (v == nullptr) {
2272  return false;
2273  }
2274  const Var* rv = dynamic_cast<const Var*>(&rhs);
2275  if (rv == nullptr) {
2276  return false;
2277  }
2278  return (v->get_which_row() == rv->get_which_row()) &&
2279  (v->get_varno() == rv->get_varno());
2280 }
2281 
2282 bool ExpressionTuple::operator==(const Expr& rhs) const {
2283  const auto rhs_tuple = dynamic_cast<const ExpressionTuple*>(&rhs);
2284  if (!rhs_tuple) {
2285  return false;
2286  }
2287  const auto& rhs_tuple_cols = rhs_tuple->getTuple();
2288  return expr_list_match(tuple_, rhs_tuple_cols);
2289 }
2290 
2291 bool Datum_equal(const SQLTypeInfo& ti, Datum val1, Datum val2) {
2292  switch (ti.get_type()) {
2293  case kBOOLEAN:
2294  return val1.boolval == val2.boolval;
2295  case kCHAR:
2296  case kVARCHAR:
2297  case kTEXT:
2298  return *val1.stringval == *val2.stringval;
2299  case kNUMERIC:
2300  case kDECIMAL:
2301  case kBIGINT:
2302  return val1.bigintval == val2.bigintval;
2303  case kINT:
2304  return val1.intval == val2.intval;
2305  case kSMALLINT:
2306  return val1.smallintval == val2.smallintval;
2307  case kTINYINT:
2308  return val1.tinyintval == val2.tinyintval;
2309  case kFLOAT:
2310  return val1.floatval == val2.floatval;
2311  case kDOUBLE:
2312  return val1.doubleval == val2.doubleval;
2313  case kTIME:
2314  case kTIMESTAMP:
2315  case kDATE:
2316  case kINTERVAL_DAY_TIME:
2317  case kINTERVAL_YEAR_MONTH:
2318  return val1.bigintval == val2.bigintval;
2319  case kPOINT:
2320  case kMULTIPOINT:
2321  case kLINESTRING:
2322  case kMULTILINESTRING:
2323  case kPOLYGON:
2324  case kMULTIPOLYGON:
2325  return *val1.stringval == *val2.stringval;
2326  default:
2327  throw std::runtime_error("Unrecognized type for Constant Datum equality: " +
2328  ti.get_type_name());
2329  }
2330  UNREACHABLE();
2331  return false;
2332 }
2333 
2334 bool Constant::operator==(const Expr& rhs) const {
2335  if (typeid(rhs) != typeid(Constant)) {
2336  return false;
2337  }
2338  const Constant& rhs_c = dynamic_cast<const Constant&>(rhs);
2339  if (type_info != rhs_c.get_type_info() || is_null != rhs_c.get_is_null()) {
2340  return false;
2341  }
2342  if (is_null && rhs_c.get_is_null()) {
2343  return true;
2344  }
2345  if (type_info.is_array()) {
2346  return false;
2347  }
2348  return Datum_equal(type_info, constval, rhs_c.get_constval());
2349 }
2350 
2351 bool UOper::operator==(const Expr& rhs) const {
2352  if (typeid(rhs) != typeid(UOper)) {
2353  return false;
2354  }
2355  const UOper& rhs_uo = dynamic_cast<const UOper&>(rhs);
2356  return optype == rhs_uo.get_optype() && *operand == *rhs_uo.get_operand();
2357 }
2358 
2359 bool BinOper::operator==(const Expr& rhs) const {
2360  if (typeid(rhs) != typeid(BinOper)) {
2361  return false;
2362  }
2363  const BinOper& rhs_bo = dynamic_cast<const BinOper&>(rhs);
2364  return optype == rhs_bo.get_optype() && *left_operand == *rhs_bo.get_left_operand() &&
2365  *right_operand == *rhs_bo.get_right_operand();
2366 }
2367 
2368 bool RangeOper::operator==(const Expr& rhs) const {
2369  if (typeid(rhs) != typeid(RangeOper)) {
2370  return false;
2371  }
2372  const RangeOper& rhs_rg = dynamic_cast<const RangeOper&>(rhs);
2373  return left_inclusive_ == rhs_rg.left_inclusive_ &&
2374  right_inclusive_ == rhs_rg.right_inclusive_ &&
2375  *left_operand_ == *rhs_rg.left_operand_ &&
2376  *right_operand_ == *rhs_rg.right_operand_;
2377 }
2378 
2379 bool CharLengthExpr::operator==(const Expr& rhs) const {
2380  if (typeid(rhs) != typeid(CharLengthExpr)) {
2381  return false;
2382  }
2383  const CharLengthExpr& rhs_cl = dynamic_cast<const CharLengthExpr&>(rhs);
2384  if (!(*arg == *rhs_cl.get_arg()) ||
2386  return false;
2387  }
2388  return true;
2389 }
2390 
2391 bool KeyForStringExpr::operator==(const Expr& rhs) const {
2392  if (typeid(rhs) != typeid(KeyForStringExpr)) {
2393  return false;
2394  }
2395  const KeyForStringExpr& rhs_cl = dynamic_cast<const KeyForStringExpr&>(rhs);
2396  if (!(*arg == *rhs_cl.get_arg())) {
2397  return false;
2398  }
2399  return true;
2400 }
2401 
2402 bool SampleRatioExpr::operator==(const Expr& rhs) const {
2403  if (typeid(rhs) != typeid(SampleRatioExpr)) {
2404  return false;
2405  }
2406  const SampleRatioExpr& rhs_cl = dynamic_cast<const SampleRatioExpr&>(rhs);
2407  if (!(*arg == *rhs_cl.get_arg())) {
2408  return false;
2409  }
2410  return true;
2411 }
2412 
2413 bool MLPredictExpr::operator==(const Expr& rhs) const {
2414  if (typeid(rhs) != typeid(MLPredictExpr)) {
2415  return false;
2416  }
2417  const MLPredictExpr& rhs_cl = dynamic_cast<const MLPredictExpr&>(rhs);
2418  if (!(*model_value_ == *rhs_cl.get_model_value())) {
2419  return false;
2420  }
2421  auto rhs_regressor_values = rhs_cl.get_regressor_values();
2422  if (regressor_values_.size() != rhs_regressor_values.size()) {
2423  return false;
2424  }
2425  for (size_t regressor_idx = 0; regressor_idx < regressor_values_.size();
2426  ++regressor_idx) {
2427  if (!(*regressor_values_[regressor_idx] == *rhs_regressor_values[regressor_idx])) {
2428  return false;
2429  }
2430  }
2431  return true;
2432 }
2433 
2434 bool PCAProjectExpr::operator==(const Expr& rhs) const {
2435  if (typeid(rhs) != typeid(PCAProjectExpr)) {
2436  return false;
2437  }
2438  const PCAProjectExpr& rhs_cl = dynamic_cast<const PCAProjectExpr&>(rhs);
2439  if (!(*model_value_ == *rhs_cl.get_model_value())) {
2440  return false;
2441  }
2442  if (!(*pc_dimension_value_ == *rhs_cl.get_pc_dimension_value())) {
2443  return false;
2444  }
2445  auto rhs_feature_values = rhs_cl.get_feature_values();
2446  if (feature_values_.size() != rhs_feature_values.size()) {
2447  return false;
2448  }
2449  for (size_t feature_idx = 0; feature_idx < feature_values_.size(); ++feature_idx) {
2450  if (!(*feature_values_[feature_idx] == *rhs_feature_values[feature_idx])) {
2451  return false;
2452  }
2453  }
2454  return true;
2455 }
2456 
2457 bool CardinalityExpr::operator==(const Expr& rhs) const {
2458  if (typeid(rhs) != typeid(CardinalityExpr)) {
2459  return false;
2460  }
2461  const CardinalityExpr& rhs_ca = dynamic_cast<const CardinalityExpr&>(rhs);
2462  if (!(*arg == *rhs_ca.get_arg())) {
2463  return false;
2464  }
2465  return true;
2466 }
2467 
2468 bool LikeExpr::operator==(const Expr& rhs) const {
2469  if (typeid(rhs) != typeid(LikeExpr)) {
2470  return false;
2471  }
2472  const LikeExpr& rhs_lk = dynamic_cast<const LikeExpr&>(rhs);
2473  if (!(*arg == *rhs_lk.get_arg()) || !(*like_expr == *rhs_lk.get_like_expr()) ||
2474  is_ilike != rhs_lk.get_is_ilike()) {
2475  return false;
2476  }
2477  if (escape_expr.get() == rhs_lk.get_escape_expr()) {
2478  return true;
2479  }
2480  if (escape_expr != nullptr && rhs_lk.get_escape_expr() != nullptr &&
2481  *escape_expr == *rhs_lk.get_escape_expr()) {
2482  return true;
2483  }
2484  return false;
2485 }
2486 
2487 bool RegexpExpr::operator==(const Expr& rhs) const {
2488  if (typeid(rhs) != typeid(RegexpExpr)) {
2489  return false;
2490  }
2491  const RegexpExpr& rhs_re = dynamic_cast<const RegexpExpr&>(rhs);
2492  if (!(*arg == *rhs_re.get_arg()) || !(*pattern_expr == *rhs_re.get_pattern_expr())) {
2493  return false;
2494  }
2495  if (escape_expr.get() == rhs_re.get_escape_expr()) {
2496  return true;
2497  }
2498  if (escape_expr != nullptr && rhs_re.get_escape_expr() != nullptr &&
2499  *escape_expr == *rhs_re.get_escape_expr()) {
2500  return true;
2501  }
2502  return false;
2503 }
2504 
2505 bool WidthBucketExpr::operator==(const Expr& rhs) const {
2506  if (typeid(rhs) != typeid(WidthBucketExpr)) {
2507  return false;
2508  }
2509  const WidthBucketExpr& rhs_l = dynamic_cast<const WidthBucketExpr&>(rhs);
2510  if (!(*target_value_ == *rhs_l.get_target_value())) {
2511  return false;
2512  }
2513  if (!(*lower_bound_ == *rhs_l.get_lower_bound())) {
2514  return false;
2515  }
2516  if (!(*upper_bound_ == *rhs_l.get_upper_bound())) {
2517  return false;
2518  }
2519  if (!(*partition_count_ == *rhs_l.get_partition_count())) {
2520  return false;
2521  }
2522  return true;
2523 }
2524 
2525 bool LikelihoodExpr::operator==(const Expr& rhs) const {
2526  if (typeid(rhs) != typeid(LikelihoodExpr)) {
2527  return false;
2528  }
2529  const LikelihoodExpr& rhs_l = dynamic_cast<const LikelihoodExpr&>(rhs);
2530  if (!(*arg == *rhs_l.get_arg())) {
2531  return false;
2532  }
2533  if (likelihood != rhs_l.get_likelihood()) {
2534  return false;
2535  }
2536  return true;
2537 }
2538 
2539 bool InValues::operator==(const Expr& rhs) const {
2540  if (typeid(rhs) != typeid(InValues)) {
2541  return false;
2542  }
2543  const InValues& rhs_iv = dynamic_cast<const InValues&>(rhs);
2544  if (!(*arg == *rhs_iv.get_arg())) {
2545  return false;
2546  }
2547  if (value_list.size() != rhs_iv.get_value_list().size()) {
2548  return false;
2549  }
2550  auto q = rhs_iv.get_value_list().begin();
2551  for (auto p : value_list) {
2552  if (!(*p == **q)) {
2553  return false;
2554  }
2555  q++;
2556  }
2557  return true;
2558 }
2559 
2560 bool AggExpr::operator==(const Expr& rhs) const {
2561  if (typeid(rhs) != typeid(AggExpr)) {
2562  return false;
2563  }
2564  const AggExpr& rhs_ae = dynamic_cast<const AggExpr&>(rhs);
2565  if (aggtype != rhs_ae.get_aggtype() || is_distinct != rhs_ae.get_is_distinct()) {
2566  return false;
2567  }
2568  if (arg.get() == rhs_ae.get_arg()) {
2569  return true;
2570  }
2571  if (arg == nullptr || rhs_ae.get_arg() == nullptr) {
2572  return false;
2573  }
2574  return *arg == *rhs_ae.get_arg();
2575 }
2576 
2577 bool CaseExpr::operator==(const Expr& rhs) const {
2578  if (typeid(rhs) != typeid(CaseExpr)) {
2579  return false;
2580  }
2581  const CaseExpr& rhs_ce = dynamic_cast<const CaseExpr&>(rhs);
2582  if (expr_pair_list.size() != rhs_ce.get_expr_pair_list().size()) {
2583  return false;
2584  }
2585  if ((else_expr == nullptr && rhs_ce.get_else_expr() != nullptr) ||
2586  (else_expr != nullptr && rhs_ce.get_else_expr() == nullptr)) {
2587  return false;
2588  }
2589  auto it = rhs_ce.get_expr_pair_list().cbegin();
2590  for (auto p : expr_pair_list) {
2591  if (!(*p.first == *it->first) || !(*p.second == *it->second)) {
2592  return false;
2593  }
2594  ++it;
2595  }
2596  return else_expr == nullptr ||
2597  (else_expr != nullptr && *else_expr == *rhs_ce.get_else_expr());
2598 }
2599 
2600 bool ExtractExpr::operator==(const Expr& rhs) const {
2601  if (typeid(rhs) != typeid(ExtractExpr)) {
2602  return false;
2603  }
2604  const ExtractExpr& rhs_ee = dynamic_cast<const ExtractExpr&>(rhs);
2605  return field_ == rhs_ee.get_field() && *from_expr_ == *rhs_ee.get_from_expr();
2606 }
2607 
2608 bool DateaddExpr::operator==(const Expr& rhs) const {
2609  if (typeid(rhs) != typeid(DateaddExpr)) {
2610  return false;
2611  }
2612  const DateaddExpr& rhs_ee = dynamic_cast<const DateaddExpr&>(rhs);
2613  return field_ == rhs_ee.get_field() && *number_ == *rhs_ee.get_number_expr() &&
2614  *datetime_ == *rhs_ee.get_datetime_expr();
2615 }
2616 
2617 bool DatediffExpr::operator==(const Expr& rhs) const {
2618  if (typeid(rhs) != typeid(DatediffExpr)) {
2619  return false;
2620  }
2621  const DatediffExpr& rhs_ee = dynamic_cast<const DatediffExpr&>(rhs);
2622  return field_ == rhs_ee.get_field() && *start_ == *rhs_ee.get_start_expr() &&
2623  *end_ == *rhs_ee.get_end_expr();
2624 }
2625 
2626 bool DatetruncExpr::operator==(const Expr& rhs) const {
2627  if (typeid(rhs) != typeid(DatetruncExpr)) {
2628  return false;
2629  }
2630  const DatetruncExpr& rhs_ee = dynamic_cast<const DatetruncExpr&>(rhs);
2631  return field_ == rhs_ee.get_field() && *from_expr_ == *rhs_ee.get_from_expr();
2632 }
2633 
2634 bool OffsetInFragment::operator==(const Expr& rhs) const {
2635  return typeid(rhs) == typeid(OffsetInFragment);
2636 }
2637 
2638 bool WindowFrame::operator==(const Expr& rhs) const {
2639  const WindowFrame& rhs_window_frame = dynamic_cast<const WindowFrame&>(rhs);
2640  if (bound_type_ == rhs_window_frame.bound_type_) {
2641  if (bound_expr_) {
2642  return rhs_window_frame.bound_expr_ &&
2643  *bound_expr_.get() == *rhs_window_frame.getBoundExpr();
2644  } else {
2645  return !rhs_window_frame.bound_expr_;
2646  }
2647  }
2648  return false;
2649 }
2650 
2651 bool WindowFunction::operator==(const Expr& rhs) const {
2652  const auto rhs_window = dynamic_cast<const WindowFunction*>(&rhs);
2653  if (!rhs_window) {
2654  return false;
2655  }
2656  if (kind_ != rhs_window->kind_ || args_.size() != rhs_window->args_.size() ||
2657  partition_keys_.size() != rhs_window->partition_keys_.size() ||
2658  order_keys_.size() != rhs_window->order_keys_.size() ||
2659  frame_bound_type_ != rhs_window->frame_bound_type_ ||
2660  frame_start_bound_.get() != rhs_window->frame_start_bound_.get() ||
2661  frame_end_bound_.get() != rhs_window->frame_end_bound_.get()) {
2662  return false;
2663  }
2664  return expr_list_match(args_, rhs_window->args_) &&
2665  expr_list_match(partition_keys_, rhs_window->partition_keys_) &&
2666  expr_list_match(order_keys_, rhs_window->order_keys_);
2667 }
2668 
2669 bool ArrayExpr::operator==(Expr const& rhs) const {
2670  if (typeid(rhs) != typeid(ArrayExpr)) {
2671  return false;
2672  }
2673  ArrayExpr const& casted_rhs = static_cast<ArrayExpr const&>(rhs);
2674  for (unsigned i = 0; i < contained_expressions_.size(); i++) {
2675  auto& lhs_expr = contained_expressions_[i];
2676  auto& rhs_expr = casted_rhs.contained_expressions_[i];
2677  if (!(lhs_expr == rhs_expr)) {
2678  return false;
2679  }
2680  }
2681  if (isNull() != casted_rhs.isNull()) {
2682  return false;
2683  }
2684 
2685  return true;
2686  ;
2687 }
2688 
2689 bool GeoUOper::operator==(const Expr& rhs) const {
2690  const auto rhs_geo = dynamic_cast<const GeoUOper*>(&rhs);
2691  if (!rhs_geo) {
2692  return false;
2693  }
2694  if (op_ != rhs_geo->getOp() || ti0_ != rhs_geo->getTypeInfo0() ||
2695  args0_.size() != rhs_geo->getArgs0().size()) {
2696  return false;
2697  }
2698  return expr_list_match(args0_, rhs_geo->getArgs0());
2699 }
2700 
2701 bool GeoBinOper::operator==(const Expr& rhs) const {
2702  const auto rhs_geo = dynamic_cast<const GeoBinOper*>(&rhs);
2703  if (!rhs_geo) {
2704  return false;
2705  }
2706  if (op_ != rhs_geo->getOp() || ti0_ != rhs_geo->getTypeInfo0() ||
2707  args0_.size() != rhs_geo->getArgs0().size()) {
2708  return false;
2709  }
2710  if (ti1_ != rhs_geo->getTypeInfo1() || args1_.size() != rhs_geo->getArgs1().size()) {
2711  return false;
2712  }
2713  return expr_list_match(args0_, rhs_geo->getArgs0()) ||
2714  expr_list_match(args1_, rhs_geo->getArgs1());
2715 }
2716 
2717 std::string ColumnVar::toString() const {
2718  std::stringstream ss;
2719  ss << "(ColumnVar " << column_key_ << ", rte: " << std::to_string(rte_idx_) << " "
2720  << get_type_info().get_type_name() << ", type: " << type_info.toString() << ") ";
2721  return ss.str();
2722 }
2723 
2724 std::string ExpressionTuple::toString() const {
2725  std::string str{"< "};
2726  for (const auto& column : tuple_) {
2727  str += column->toString();
2728  }
2729  str += "> ";
2730  return str;
2731 }
2732 
2733 std::string Var::toString() const {
2734  std::stringstream ss;
2735  ss << "(Var " << column_key_ << ", rte: " << std::to_string(rte_idx_)
2736  << ", which_row: " << std::to_string(which_row)
2737  << ", varno: " << std::to_string(varno) + ") ";
2738  return ss.str();
2739 }
2740 
2741 std::string Constant::toString() const {
2742  std::string str{"(Const "};
2743  if (is_null) {
2744  str += "NULL";
2745  } else if (type_info.is_array()) {
2746  const auto& elem_ti = type_info.get_elem_type();
2747  str += ::toString(type_info.get_type()) + ": " + ::toString(elem_ti.get_type());
2748  } else {
2749  str += DatumToString(constval, type_info);
2750  }
2751  str += ") ";
2752  return str;
2753 }
2754 
2755 std::string UOper::toString() const {
2756  std::string op;
2757  switch (optype) {
2758  case kNOT:
2759  op = "NOT ";
2760  break;
2761  case kUMINUS:
2762  op = "- ";
2763  break;
2764  case kISNULL:
2765  op = "IS NULL ";
2766  break;
2767  case kEXISTS:
2768  op = "EXISTS ";
2769  break;
2770  case kCAST:
2771  op = "CAST " + type_info.get_type_name() + "(" +
2773  std::to_string(type_info.get_scale()) + ") " +
2776  break;
2777  case kUNNEST:
2778  op = "UNNEST ";
2779  break;
2780  default:
2781  break;
2782  }
2783  return "(" + op + operand->toString() + ") ";
2784 }
2785 
2786 std::string BinOper::toString() const {
2787  std::string op;
2788  switch (optype) {
2789  case kEQ:
2790  op = "= ";
2791  break;
2792  case kNE:
2793  op = "<> ";
2794  break;
2795  case kLT:
2796  op = "< ";
2797  break;
2798  case kLE:
2799  op = "<= ";
2800  break;
2801  case kGT:
2802  op = "> ";
2803  break;
2804  case kGE:
2805  op = ">= ";
2806  break;
2807  case kAND:
2808  op = "AND ";
2809  break;
2810  case kOR:
2811  op = "OR ";
2812  break;
2813  case kMINUS:
2814  op = "- ";
2815  break;
2816  case kPLUS:
2817  op = "+ ";
2818  break;
2819  case kMULTIPLY:
2820  op = "* ";
2821  break;
2822  case kDIVIDE:
2823  op = "/ ";
2824  break;
2825  case kMODULO:
2826  op = "% ";
2827  break;
2828  case kARRAY_AT:
2829  op = "[] ";
2830  break;
2831  case kBBOX_INTERSECT:
2832  op = "BBOX_INTERSECT ";
2833  break;
2834  default:
2835  break;
2836  }
2837  std::string str{"("};
2838  str += op;
2839  if (qualifier == kANY) {
2840  str += "ANY ";
2841  } else if (qualifier == kALL) {
2842  str += "ALL ";
2843  }
2844  str += left_operand->toString();
2845  str += right_operand->toString();
2846  str += ") ";
2847  return str;
2848 }
2849 
2850 std::string RangeOper::toString() const {
2851  const std::string lhs = left_inclusive_ ? "[" : "(";
2852  const std::string rhs = right_inclusive_ ? "]" : ")";
2853  return "(RangeOper " + lhs + " " + left_operand_->toString() + " , " +
2854  right_operand_->toString() + " " + rhs + " )";
2855 }
2856 
2857 std::string MLPredictExpr::toString() const {
2858  std::stringstream ss;
2859  ss << "ML_PREDICT(Model: ";
2860  ss << model_value_->toString();
2861  ss << " Regressors: ";
2862  for (const auto& regressor_value : regressor_values_) {
2863  ss << regressor_value->toString() << " ";
2864  }
2865  ss << ") ";
2866  return ss.str();
2867 }
2868 
2869 std::string PCAProjectExpr::toString() const {
2870  std::stringstream ss;
2871  ss << "PCA_PROJECT(Model: ";
2872  ss << model_value_->toString();
2873  ss << " Features: ";
2874  for (const auto& feature_value : feature_values_) {
2875  ss << feature_value->toString() << " ";
2876  }
2877  ss << " PC Dimension: ";
2878  ss << pc_dimension_value_->toString() << " ";
2879  ss << ") ";
2880  return ss.str();
2881 }
2882 
2883 std::string Subquery::toString() const {
2884  return "(Subquery ) ";
2885 }
2886 
2887 std::string InValues::toString() const {
2888  std::string str{"(IN "};
2889  str += arg->toString();
2890  str += "(";
2891  int cnt = 0;
2892  bool shorted_value_list_str = false;
2893  for (auto e : value_list) {
2894  str += e->toString();
2895  cnt++;
2896  if (cnt > 4) {
2897  shorted_value_list_str = true;
2898  break;
2899  }
2900  }
2901  if (shorted_value_list_str) {
2902  str += "... | ";
2903  str += "Total # values: ";
2904  str += std::to_string(value_list.size());
2905  }
2906  str += ") ";
2907  return str;
2908 }
2909 
2910 std::shared_ptr<Analyzer::Expr> InIntegerSet::deep_copy() const {
2911  return std::make_shared<InIntegerSet>(arg, value_list, get_type_info().get_notnull());
2912 }
2913 
2914 bool InIntegerSet::operator==(const Expr& rhs) const {
2915  if (!dynamic_cast<const InIntegerSet*>(&rhs)) {
2916  return false;
2917  }
2918  const auto& rhs_in_integer_set = static_cast<const InIntegerSet&>(rhs);
2919  return *arg == *rhs_in_integer_set.arg && value_list == rhs_in_integer_set.value_list;
2920 }
2921 
2922 std::string InIntegerSet::toString() const {
2923  std::string str{"(IN_INTEGER_SET "};
2924  str += arg->toString();
2925  str += "( ";
2926  int cnt = 0;
2927  bool shorted_value_list_str = false;
2928  for (const auto e : value_list) {
2929  str += std::to_string(e) + " ";
2930  cnt++;
2931  if (cnt > 4) {
2932  shorted_value_list_str = true;
2933  break;
2934  }
2935  }
2936  if (shorted_value_list_str) {
2937  str += "... | ";
2938  str += "Total # values: ";
2939  str += std::to_string(value_list.size());
2940  }
2941  str += ") ";
2942  return str;
2943 }
2944 
2945 std::string CharLengthExpr::toString() const {
2946  std::string str;
2947  if (calc_encoded_length) {
2948  str += "CHAR_LENGTH(";
2949  } else {
2950  str += "LENGTH(";
2951  }
2952  str += arg->toString();
2953  str += ") ";
2954  return str;
2955 }
2956 
2957 std::string KeyForStringExpr::toString() const {
2958  std::string str{"KEY_FOR_STRING("};
2959  str += arg->toString();
2960  str += ") ";
2961  return str;
2962 }
2963 
2964 std::string SampleRatioExpr::toString() const {
2965  std::string str{"SAMPLE_RATIO("};
2966  str += arg->toString();
2967  str += ") ";
2968  return str;
2969 }
2970 
2971 std::string CardinalityExpr::toString() const {
2972  std::string str{"CARDINALITY("};
2973  str += arg->toString();
2974  str += ") ";
2975  return str;
2976 }
2977 
2978 std::string LikeExpr::toString() const {
2979  std::string str{"(LIKE "};
2980  str += arg->toString();
2981  str += like_expr->toString();
2982  if (escape_expr) {
2983  str += escape_expr->toString();
2984  }
2985  str += ") ";
2986  return str;
2987 }
2988 
2989 std::string RegexpExpr::toString() const {
2990  std::string str{"(REGEXP "};
2991  str += arg->toString();
2992  str += pattern_expr->toString();
2993  if (escape_expr) {
2994  str += escape_expr->toString();
2995  }
2996  str += ") ";
2997  return str;
2998 }
2999 
3000 std::string WidthBucketExpr::toString() const {
3001  std::string str{"(WIDTH_BUCKET "};
3002  str += target_value_->toString();
3003  str += lower_bound_->toString();
3004  str += upper_bound_->toString();
3005  str += partition_count_->toString();
3006  return str + ") ";
3007 }
3008 
3009 std::string LikelihoodExpr::toString() const {
3010  std::string str{"(LIKELIHOOD "};
3011  str += arg->toString();
3012  return str + " " + std::to_string(likelihood) + ") ";
3013 }
3014 
3015 std::string AggExpr::toString() const {
3016  std::string agg;
3017  switch (aggtype) {
3018  case kAVG:
3019  agg = "AVG ";
3020  break;
3021  case kMIN:
3022  agg = "MIN ";
3023  break;
3024  case kMAX:
3025  agg = "MAX ";
3026  break;
3027  case kSUM:
3028  agg = "SUM ";
3029  break;
3030  case kCOUNT:
3031  agg = "COUNT ";
3032  break;
3034  agg = "APPROX_COUNT_DISTINCT";
3035  break;
3036  case kAPPROX_QUANTILE:
3037  agg = "APPROX_PERCENTILE";
3038  break;
3039  case kSINGLE_VALUE:
3040  agg = "SINGLE_VALUE";
3041  break;
3042  case kSAMPLE:
3043  agg = "SAMPLE";
3044  break;
3045  case kMODE:
3046  agg = "MODE";
3047  break;
3048  case kCOUNT_IF:
3049  agg = "COUNT_IF";
3050  break;
3051  case kSUM_IF:
3052  agg = "SUM_IF";
3053  break;
3054  default:
3055  UNREACHABLE() << "Unhandled aggtype: " << aggtype;
3056  break;
3057  }
3058  std::string str{"(" + agg};
3059  if (is_distinct) {
3060  str += "DISTINCT ";
3061  }
3062  if (arg) {
3063  str += arg->toString();
3064  } else {
3065  str += "*";
3066  }
3067  return str + ") ";
3068 }
3069 
3070 std::string CaseExpr::toString() const {
3071  std::string str{"CASE "};
3072  for (auto p : expr_pair_list) {
3073  str += "(";
3074  str += p.first->toString();
3075  str += ", ";
3076  str += p.second->toString();
3077  str += ") ";
3078  }
3079  if (else_expr) {
3080  str += "ELSE ";
3081  str += else_expr->toString();
3082  }
3083  str += " END ";
3084  return str;
3085 }
3086 
3087 std::string ExtractExpr::toString() const {
3088  return "EXTRACT(" + std::to_string(field_) + " FROM " + from_expr_->toString() + ") ";
3089 }
3090 
3091 std::string DateaddExpr::toString() const {
3092  return "DATEADD(" + std::to_string(field_) + " NUMBER " + number_->toString() +
3093  " DATETIME " + datetime_->toString() + ") ";
3094 }
3095 
3096 std::string DatediffExpr::toString() const {
3097  return "DATEDIFF(" + std::to_string(field_) + " START " + start_->toString() + " END " +
3098  end_->toString() + ") ";
3099 }
3100 
3101 std::string DatetruncExpr::toString() const {
3102  return "DATE_TRUNC(" + std::to_string(field_) + " , " + from_expr_->toString() + ") ";
3103 }
3104 
3105 std::string OffsetInFragment::toString() const {
3106  return "(OffsetInFragment) ";
3107 }
3108 
3109 std::string WindowFrame::toString() const {
3110  std::ostringstream oss;
3111  auto bound_str = bound_expr_ ? bound_expr_->toString() : "None";
3112  oss << bound_type_ << " " << bound_str;
3113  return oss.str();
3114 }
3115 
3116 std::string WindowFunction::toString() const {
3117  std::ostringstream oss;
3118  oss << "WindowFunction(" << kind_;
3119  for (const auto& arg : args_) {
3120  oss << " " << arg->toString();
3121  }
3122  if (hasFraming()) {
3123  oss << " Frame{";
3124  switch (frame_bound_type_) {
3125  case FrameBoundType::ROW: {
3126  oss << "ROW";
3127  break;
3128  }
3129  case FrameBoundType::RANGE: {
3130  oss << "RANGE";
3131  break;
3132  }
3133  default: {
3134  UNREACHABLE()
3135  << "Two bound types are supported for window framing: ROW and RANGE.";
3136  break;
3137  }
3138  }
3139  oss << " BETWEEN : " + frame_start_bound_->toString();
3140  oss << " AND : " + frame_end_bound_->toString();
3141  } else {
3142  if (!order_keys_.empty()) {
3143  oss << " (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)";
3144  } else {
3145  oss << " (RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)";
3146  }
3147  }
3148  oss << "} )";
3149  return oss.str();
3150 }
3151 
3152 std::string ArrayExpr::toString() const {
3153  std::string str{"ARRAY["};
3154 
3155  auto iter(contained_expressions_.begin());
3156  while (iter != contained_expressions_.end()) {
3157  str += (*iter)->toString();
3158  if (iter + 1 != contained_expressions_.end()) {
3159  str += ", ";
3160  }
3161  iter++;
3162  }
3163  str += "]";
3164  return str;
3165 }
3166 
3167 std::string GeoUOper::toString() const {
3168  std::string fn;
3169  switch (op_) {
3171  fn = "Geo";
3172  break;
3174  fn = "ST_IsEmpty";
3175  break;
3177  fn = "ST_IsValid";
3178  break;
3180  fn = "ST_IsConcaveHull";
3181  break;
3183  fn = "ST_IsConvexHull";
3184  break;
3185  default:
3186  fn = "Geo_UNKNOWN";
3187  break;
3188  }
3189  std::string result = fn + "(";
3190  for (const auto& arg : args0_) {
3191  result += " " + arg->toString();
3192  }
3193  return result + " ) ";
3194 }
3195 
3196 std::string GeoBinOper::toString() const {
3197  std::string fn;
3198  switch (op_) {
3200  fn = "ST_Intersection";
3201  break;
3203  fn = "ST_Difference";
3204  break;
3206  fn = "ST_Union";
3207  break;
3209  fn = "ST_Buffer";
3210  break;
3211  default:
3212  fn = "Geo_UNKNOWN";
3213  break;
3214  }
3215  std::string result = fn + "(";
3216  // TODO: generate wkt
3217  for (const auto& arg : args0_) {
3218  result += " " + arg->toString();
3219  }
3220  for (const auto& arg : args1_) {
3221  result += " " + arg->toString();
3222  }
3223  return result + " ) ";
3224 }
3225 
3226 std::string TargetEntry::toString() const {
3227  std::string str{"(" + resname + " "};
3228  str += expr->toString();
3229  if (unnest) {
3230  str += " UNNEST";
3231  }
3232  str += ") ";
3233  return str;
3234 }
3235 
3236 std::string OrderEntry::toString() const {
3237  std::string str{std::to_string(tle_no)};
3238  if (is_desc) {
3239  str += " desc";
3240  }
3241  if (nulls_first) {
3242  str += " nulls first";
3243  }
3244  str += " ";
3245  return str;
3246 }
3247 
3248 void Expr::add_unique(std::list<const Expr*>& expr_list) const {
3249  // only add unique instances to the list
3250  for (auto e : expr_list) {
3251  if (*e == *this) {
3252  return;
3253  }
3254  }
3255  expr_list.push_back(this);
3256 }
3257 
3258 void BinOper::find_expr(std::function<bool(const Expr*)> f,
3259  std::list<const Expr*>& expr_list) const {
3260  if (f(this)) {
3261  add_unique(expr_list);
3262  return;
3263  }
3264  left_operand->find_expr(f, expr_list);
3265  right_operand->find_expr(f, expr_list);
3266 }
3267 
3268 void UOper::find_expr(std::function<bool(const Expr*)> f,
3269  std::list<const Expr*>& expr_list) const {
3270  if (f(this)) {
3271  add_unique(expr_list);
3272  return;
3273  }
3274  operand->find_expr(f, expr_list);
3275 }
3276 
3277 void InValues::find_expr(std::function<bool(const Expr*)> f,
3278  std::list<const Expr*>& expr_list) const {
3279  if (f(this)) {
3280  add_unique(expr_list);
3281  return;
3282  }
3283  arg->find_expr(f, expr_list);
3284  for (auto e : value_list) {
3285  e->find_expr(f, expr_list);
3286  }
3287 }
3288 
3289 void MLPredictExpr::find_expr(std::function<bool(const Expr*)> f,
3290  std::list<const Expr*>& expr_list) const {
3291  if (f(this)) {
3292  add_unique(expr_list);
3293  return;
3294  }
3295  for (auto& r : regressor_values_) {
3296  r->find_expr(f, expr_list);
3297  }
3298 }
3299 
3300 void PCAProjectExpr::find_expr(std::function<bool(const Expr*)> f,
3301  std::list<const Expr*>& expr_list) const {
3302  if (f(this)) {
3303  add_unique(expr_list);
3304  return;
3305  }
3306  for (auto& feature_value : feature_values_) {
3307  feature_value->find_expr(f, expr_list);
3308  }
3309 }
3310 
3311 void CharLengthExpr::find_expr(std::function<bool(const Expr*)> f,
3312  std::list<const Expr*>& expr_list) const {
3313  if (f(this)) {
3314  add_unique(expr_list);
3315  return;
3316  }
3317  arg->find_expr(f, expr_list);
3318 }
3319 
3320 void KeyForStringExpr::find_expr(std::function<bool(const Expr*)> f,
3321  std::list<const Expr*>& expr_list) const {
3322  if (f(this)) {
3323  add_unique(expr_list);
3324  return;
3325  }
3326  arg->find_expr(f, expr_list);
3327 }
3328 
3329 void SampleRatioExpr::find_expr(std::function<bool(const Expr*)> f,
3330  std::list<const Expr*>& expr_list) const {
3331  if (f(this)) {
3332  add_unique(expr_list);
3333  return;
3334  }
3335  arg->find_expr(f, expr_list);
3336 }
3337 
3338 void StringOper::find_expr(std::function<bool(const Expr*)> f,
3339  std::list<const Expr*>& expr_list) const {
3340  if (f(this)) {
3341  add_unique(expr_list);
3342  return;
3343  }
3344  for (const auto& arg : args_) {
3345  arg->find_expr(f, expr_list);
3346  }
3347 }
3348 
3349 void CardinalityExpr::find_expr(std::function<bool(const Expr*)> f,
3350  std::list<const Expr*>& expr_list) const {
3351  if (f(this)) {
3352  add_unique(expr_list);
3353  return;
3354  }
3355  arg->find_expr(f, expr_list);
3356 }
3357 
3358 void LikeExpr::find_expr(std::function<bool(const Expr*)> f,
3359  std::list<const Expr*>& expr_list) const {
3360  if (f(this)) {
3361  add_unique(expr_list);
3362  return;
3363  }
3364  arg->find_expr(f, expr_list);
3365  like_expr->find_expr(f, expr_list);
3366  if (escape_expr != nullptr) {
3367  escape_expr->find_expr(f, expr_list);
3368  }
3369 }
3370 
3371 void RegexpExpr::find_expr(std::function<bool(const Expr*)> f,
3372  std::list<const Expr*>& expr_list) const {
3373  if (f(this)) {
3374  add_unique(expr_list);
3375  return;
3376  }
3377  arg->find_expr(f, expr_list);
3378  pattern_expr->find_expr(f, expr_list);
3379  if (escape_expr != nullptr) {
3380  escape_expr->find_expr(f, expr_list);
3381  }
3382 }
3383 
3384 void WidthBucketExpr::find_expr(std::function<bool(const Expr*)> f,
3385  std::list<const Expr*>& expr_list) const {
3386  if (f(this)) {
3387  add_unique(expr_list);
3388  return;
3389  }
3390  target_value_->find_expr(f, expr_list);
3391  lower_bound_->find_expr(f, expr_list);
3392  upper_bound_->find_expr(f, expr_list);
3393  partition_count_->find_expr(f, expr_list);
3394 }
3395 
3396 void LikelihoodExpr::find_expr(std::function<bool(const Expr*)> f,
3397  std::list<const Expr*>& expr_list) const {
3398  if (f(this)) {
3399  add_unique(expr_list);
3400  return;
3401  }
3402  arg->find_expr(f, expr_list);
3403 }
3404 
3405 void AggExpr::find_expr(std::function<bool(const Expr*)> f,
3406  std::list<const Expr*>& expr_list) const {
3407  if (f(this)) {
3408  add_unique(expr_list);
3409  return;
3410  }
3411  if (arg != nullptr) {
3412  arg->find_expr(f, expr_list);
3413  }
3414 }
3415 
3416 void CaseExpr::find_expr(std::function<bool(const Expr*)> f,
3417  std::list<const Expr*>& expr_list) const {
3418  if (f(this)) {
3419  add_unique(expr_list);
3420  return;
3421  }
3422  for (auto p : expr_pair_list) {
3423  p.first->find_expr(f, expr_list);
3424  p.second->find_expr(f, expr_list);
3425  }
3426  if (else_expr != nullptr) {
3427  else_expr->find_expr(f, expr_list);
3428  }
3429 }
3430 
3431 void ExtractExpr::find_expr(std::function<bool(const Expr*)> f,
3432  std::list<const Expr*>& expr_list) const {
3433  if (f(this)) {
3434  add_unique(expr_list);
3435  return;
3436  }
3437  from_expr_->find_expr(f, expr_list);
3438 }
3439 
3440 void DateaddExpr::find_expr(std::function<bool(const Expr*)> f,
3441  std::list<const Expr*>& expr_list) const {
3442  if (f(this)) {
3443  add_unique(expr_list);
3444  return;
3445  }
3446  number_->find_expr(f, expr_list);
3447  datetime_->find_expr(f, expr_list);
3448 }
3449 
3450 void DatediffExpr::find_expr(std::function<bool(const Expr*)> f,
3451  std::list<const Expr*>& expr_list) const {
3452  if (f(this)) {
3453  add_unique(expr_list);
3454  return;
3455  }
3456  start_->find_expr(f, expr_list);
3457  end_->find_expr(f, expr_list);
3458 }
3459 
3460 void DatetruncExpr::find_expr(std::function<bool(const Expr*)> f,
3461  std::list<const Expr*>& expr_list) const {
3462  if (f(this)) {
3463  add_unique(expr_list);
3464  return;
3465  }
3466  from_expr_->find_expr(f, expr_list);
3467 }
3468 
3469 void FunctionOper::find_expr(std::function<bool(const Expr*)> f,
3470  std::list<const Expr*>& expr_list) const {
3471  if (f(this)) {
3472  add_unique(expr_list);
3473  return;
3474  }
3475  for (const auto& arg : args_) {
3476  arg->find_expr(f, expr_list);
3477  }
3478 }
3479 
3480 void CaseExpr::collect_rte_idx(std::set<int>& rte_idx_set) const {
3481  for (auto p : expr_pair_list) {
3482  p.first->collect_rte_idx(rte_idx_set);
3483  p.second->collect_rte_idx(rte_idx_set);
3484  }
3485  if (else_expr != nullptr) {
3486  else_expr->collect_rte_idx(rte_idx_set);
3487  }
3488 }
3489 
3490 void ExtractExpr::collect_rte_idx(std::set<int>& rte_idx_set) const {
3491  from_expr_->collect_rte_idx(rte_idx_set);
3492 }
3493 
3494 void DateaddExpr::collect_rte_idx(std::set<int>& rte_idx_set) const {
3495  number_->collect_rte_idx(rte_idx_set);
3496  datetime_->collect_rte_idx(rte_idx_set);
3497 }
3498 
3499 void DatediffExpr::collect_rte_idx(std::set<int>& rte_idx_set) const {
3500  start_->collect_rte_idx(rte_idx_set);
3501  end_->collect_rte_idx(rte_idx_set);
3502 }
3503 
3504 void DatetruncExpr::collect_rte_idx(std::set<int>& rte_idx_set) const {
3505  from_expr_->collect_rte_idx(rte_idx_set);
3506 }
3507 
3508 void ArrayExpr::collect_rte_idx(std::set<int>& rte_idx_set) const {
3509  for (unsigned i = 0; i < getElementCount(); i++) {
3510  const auto expr = getElement(i);
3511  expr->collect_rte_idx(rte_idx_set);
3512  }
3513 }
3514 
3515 void StringOper::collect_rte_idx(std::set<int>& rte_idx_set) const {
3516  for (const auto& arg : args_) {
3517  arg->collect_rte_idx(rte_idx_set);
3518  }
3519 }
3520 
3521 void FunctionOper::collect_rte_idx(std::set<int>& rte_idx_set) const {
3522  for (unsigned i = 0; i < getArity(); i++) {
3523  const auto expr = getArg(i);
3524  expr->collect_rte_idx(rte_idx_set);
3525  }
3526 }
3527 
3529  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3530  bool include_agg) const {
3531  for (auto p : expr_pair_list) {
3532  p.first->collect_column_var(colvar_set, include_agg);
3533  p.second->collect_column_var(colvar_set, include_agg);
3534  }
3535  if (else_expr != nullptr) {
3536  else_expr->collect_column_var(colvar_set, include_agg);
3537  }
3538 }
3539 
3541  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3542  bool include_agg) const {
3543  from_expr_->collect_column_var(colvar_set, include_agg);
3544 }
3545 
3547  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3548  bool include_agg) const {
3549  number_->collect_column_var(colvar_set, include_agg);
3550  datetime_->collect_column_var(colvar_set, include_agg);
3551 }
3552 
3554  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3555  bool include_agg) const {
3556  start_->collect_column_var(colvar_set, include_agg);
3557  end_->collect_column_var(colvar_set, include_agg);
3558 }
3559 
3561  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3562  bool include_agg) const {
3563  from_expr_->collect_column_var(colvar_set, include_agg);
3564 }
3565 
3567  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3568  bool include_agg) const {
3569  for (unsigned i = 0; i < getElementCount(); i++) {
3570  const auto expr = getElement(i);
3571  expr->collect_column_var(colvar_set, include_agg);
3572  }
3573 }
3574 
3576  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3577  bool include_agg) const {
3578  for (const auto& arg : args_) {
3579  arg->collect_column_var(colvar_set, include_agg);
3580  }
3581 }
3582 
3584  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
3585  bool include_agg) const {
3586  for (unsigned i = 0; i < getArity(); i++) {
3587  const auto expr = getArg(i);
3588  expr->collect_column_var(colvar_set, include_agg);
3589  }
3590 }
3591 
3593  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
3594  for (auto p : expr_pair_list) {
3595  p.first->check_group_by(groupby);
3596  p.second->check_group_by(groupby);
3597  }
3598  if (else_expr != nullptr) {
3599  else_expr->check_group_by(groupby);
3600  }
3601 }
3602 
3604  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
3605  from_expr_->check_group_by(groupby);
3606 }
3607 
3609  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
3610  number_->check_group_by(groupby);
3611  datetime_->check_group_by(groupby);
3612 }
3613 
3615  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
3616  start_->check_group_by(groupby);
3617  end_->check_group_by(groupby);
3618 }
3619 
3621  const std::list<std::shared_ptr<Analyzer::Expr>>& groupby) const {
3622  from_expr_->check_group_by(groupby);
3623 }
3624 
3625 void CaseExpr::get_domain(DomainSet& domain_set) const {
3626  for (const auto& p : expr_pair_list) {
3627  const auto c = std::dynamic_pointer_cast<const Constant>(p.second);
3628  if (c != nullptr) {
3629  c->add_unique(domain_set);
3630  } else {
3631  const auto v = std::dynamic_pointer_cast<const ColumnVar>(p.second);
3632  if (v != nullptr) {
3633  v->add_unique(domain_set);
3634  } else {
3635  const auto cast = std::dynamic_pointer_cast<const UOper>(p.second);
3636  if (cast != nullptr && cast->get_optype() == kCAST) {
3637  const Constant* c = dynamic_cast<const Constant*>(cast->get_operand());
3638  if (c != nullptr) {
3639  cast->add_unique(domain_set);
3640  continue;
3641  } else {
3642  const auto v = std::dynamic_pointer_cast<const ColumnVar>(p.second);
3643  if (v != nullptr) {
3644  v->add_unique(domain_set);
3645  continue;
3646  }
3647  }
3648  }
3649  p.second->get_domain(domain_set);
3650  if (domain_set.empty()) {
3651  return;
3652  }
3653  }
3654  }
3655  }
3656  if (else_expr != nullptr) {
3657  const auto c = std::dynamic_pointer_cast<const Constant>(else_expr);
3658  if (c != nullptr) {
3659  c->add_unique(domain_set);
3660  } else {
3661  const auto v = std::dynamic_pointer_cast<const ColumnVar>(else_expr);
3662  if (v != nullptr) {
3663  v->add_unique(domain_set);
3664  } else {
3665  const auto cast = std::dynamic_pointer_cast<const UOper>(else_expr);
3666  if (cast != nullptr && cast->get_optype() == kCAST) {
3667  const Constant* c = dynamic_cast<const Constant*>(cast->get_operand());
3668  if (c != nullptr) {
3669  c->add_unique(domain_set);
3670  } else {
3671  const auto v = std::dynamic_pointer_cast<const ColumnVar>(else_expr);
3672  if (v != nullptr) {
3673  v->add_unique(domain_set);
3674  }
3675  }
3676  } else {
3677  else_expr->get_domain(domain_set);
3678  }
3679  }
3680  }
3681  }
3682 }
3683 
3684 std::shared_ptr<Analyzer::Expr> StringOper::deep_copy() const {
3685  std::vector<std::shared_ptr<Analyzer::Expr>> args_copy;
3686  for (const auto& arg : args_) {
3687  args_copy.emplace_back(arg->deep_copy());
3688  }
3689  std::vector<std::shared_ptr<Analyzer::Expr>> chained_string_op_exprs_copy;
3690  for (const auto& chained_string_op_expr : chained_string_op_exprs_) {
3691  chained_string_op_exprs_copy.emplace_back(chained_string_op_expr->deep_copy());
3692  }
3693  return makeExpr<Analyzer::StringOper>(kind_,
3694  get_type_info(),
3695  std::move(args_copy),
3696  std::move(chained_string_op_exprs_copy));
3697 }
3698 
3699 std::shared_ptr<Analyzer::Expr> LowerStringOper::deep_copy() const {
3700  return makeExpr<Analyzer::LowerStringOper>(
3701  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3702 }
3703 
3704 std::shared_ptr<Analyzer::Expr> UpperStringOper::deep_copy() const {
3705  return makeExpr<Analyzer::UpperStringOper>(
3706  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3707 }
3708 
3709 std::shared_ptr<Analyzer::Expr> InitCapStringOper::deep_copy() const {
3710  return makeExpr<Analyzer::InitCapStringOper>(
3711  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3712 }
3713 
3714 std::shared_ptr<Analyzer::Expr> ReverseStringOper::deep_copy() const {
3715  return makeExpr<Analyzer::ReverseStringOper>(
3716  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3717 }
3718 
3719 std::shared_ptr<Analyzer::Expr> RepeatStringOper::deep_copy() const {
3720  return makeExpr<Analyzer::RepeatStringOper>(
3721  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3722 }
3723 
3724 std::shared_ptr<Analyzer::Expr> PadStringOper::deep_copy() const {
3725  return makeExpr<Analyzer::PadStringOper>(
3726  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3727 }
3728 
3729 std::shared_ptr<Analyzer::Expr> TrimStringOper::deep_copy() const {
3730  return makeExpr<Analyzer::TrimStringOper>(
3731  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3732 }
3733 
3734 std::shared_ptr<Analyzer::Expr> SubstringStringOper::deep_copy() const {
3735  return makeExpr<Analyzer::SubstringStringOper>(
3736  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3737 }
3738 
3739 std::shared_ptr<Analyzer::Expr> ReplaceStringOper::deep_copy() const {
3740  return makeExpr<Analyzer::ReplaceStringOper>(
3741  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3742 }
3743 
3744 std::shared_ptr<Analyzer::Expr> OverlayStringOper::deep_copy() const {
3745  return makeExpr<Analyzer::OverlayStringOper>(
3746  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3747 }
3748 
3749 std::shared_ptr<Analyzer::Expr> ConcatStringOper::deep_copy() const {
3750  return makeExpr<Analyzer::ConcatStringOper>(
3751  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3752 }
3753 
3754 std::shared_ptr<Analyzer::Expr> SplitPartStringOper::deep_copy() const {
3755  return makeExpr<Analyzer::SplitPartStringOper>(
3756  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3757 }
3758 
3759 std::shared_ptr<Analyzer::Expr> RegexpReplaceStringOper::deep_copy() const {
3760  return makeExpr<Analyzer::RegexpReplaceStringOper>(
3761  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3762 }
3763 
3764 std::shared_ptr<Analyzer::Expr> RegexpSubstrStringOper::deep_copy() const {
3765  return makeExpr<Analyzer::RegexpSubstrStringOper>(
3766  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3767 }
3768 
3769 std::shared_ptr<Analyzer::Expr> RegexpCountStringOper::deep_copy() const {
3770  return makeExpr<Analyzer::RegexpCountStringOper>(
3771  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3772 }
3773 
3774 std::shared_ptr<Analyzer::Expr> JsonValueStringOper::deep_copy() const {
3775  return makeExpr<Analyzer::JsonValueStringOper>(
3776  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3777 }
3778 
3779 std::shared_ptr<Analyzer::Expr> Base64EncodeStringOper::deep_copy() const {
3780  return makeExpr<Analyzer::Base64EncodeStringOper>(
3781  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3782 }
3783 
3784 std::shared_ptr<Analyzer::Expr> Base64DecodeStringOper::deep_copy() const {
3785  return makeExpr<Analyzer::Base64DecodeStringOper>(
3786  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3787 }
3788 
3789 std::shared_ptr<Analyzer::Expr> UrlEncodeStringOper::deep_copy() const {
3790  return makeExpr<Analyzer::UrlEncodeStringOper>(
3791  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3792 }
3793 
3794 std::shared_ptr<Analyzer::Expr> UrlDecodeStringOper::deep_copy() const {
3795  return makeExpr<Analyzer::UrlDecodeStringOper>(
3796  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3797 }
3798 
3799 std::shared_ptr<Analyzer::Expr> TryStringCastOper::deep_copy() const {
3800  return makeExpr<Analyzer::TryStringCastOper>(
3801  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3802 }
3803 
3804 std::shared_ptr<Analyzer::Expr> PositionStringOper::deep_copy() const {
3805  return makeExpr<Analyzer::PositionStringOper>(
3806  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3807 }
3808 
3809 std::shared_ptr<Analyzer::Expr> JarowinklerSimilarityStringOper::deep_copy() const {
3810  return makeExpr<Analyzer::JarowinklerSimilarityStringOper>(
3811  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3812 }
3813 
3814 std::shared_ptr<Analyzer::Expr> LevenshteinDistanceStringOper::deep_copy() const {
3815  return makeExpr<Analyzer::LevenshteinDistanceStringOper>(
3816  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3817 }
3818 
3819 std::shared_ptr<Analyzer::Expr> HashStringOper::deep_copy() const {
3820  return makeExpr<Analyzer::HashStringOper>(
3821  std::dynamic_pointer_cast<Analyzer::StringOper>(StringOper::deep_copy()));
3822 }
3823 
3824 std::shared_ptr<Analyzer::Expr> FunctionOper::deep_copy() const {
3825  std::vector<std::shared_ptr<Analyzer::Expr>> args_copy;
3826  for (size_t i = 0; i < getArity(); ++i) {
3827  args_copy.push_back(getArg(i)->deep_copy());
3828  }
3829  return makeExpr<Analyzer::FunctionOper>(type_info, getName(), args_copy);
3830 }
3831 
3832 bool StringOper::operator==(const Expr& rhs) const {
3833  const auto rhs_string_oper = dynamic_cast<const StringOper*>(&rhs);
3834 
3835  if (!rhs_string_oper) {
3836  return false;
3837  }
3838 
3839  if (get_kind() != rhs_string_oper->get_kind()) {
3840  return false;
3841  }
3842  if (getArity() != rhs_string_oper->getArity()) {
3843  return false;
3844  }
3845 
3846  for (size_t i = 0; i < getArity(); ++i) {
3847  if (!(*getArg(i) == *(rhs_string_oper->getArg(i)))) {
3848  return false;
3849  }
3850  }
3851  if (chained_string_op_exprs_.size() !=
3852  rhs_string_oper->chained_string_op_exprs_.size()) {
3853  return false;
3854  }
3855  for (size_t i = 0; i < chained_string_op_exprs_.size(); ++i) {
3856  if (!(*(chained_string_op_exprs_[i]) ==
3857  *(rhs_string_oper->chained_string_op_exprs_[i]))) {
3858  return false;
3859  }
3860  }
3861  return true;
3862 }
3863 
3864 bool FunctionOper::operator==(const Expr& rhs) const {
3865  if (type_info != rhs.get_type_info()) {
3866  return false;
3867  }
3868  const auto rhs_func_oper = dynamic_cast<const FunctionOper*>(&rhs);
3869  if (!rhs_func_oper) {
3870  return false;
3871  }
3872  if (getName() != rhs_func_oper->getName()) {
3873  return false;
3874  }
3875  if (getArity() != rhs_func_oper->getArity()) {
3876  return false;
3877  }
3878  for (size_t i = 0; i < getArity(); ++i) {
3879  if (!(*getArg(i) == *(rhs_func_oper->getArg(i)))) {
3880  return false;
3881  }
3882  }
3883  return true;
3884 }
3885 
3886 std::string StringOper::toString() const {
3887  std::string str{"(" + ::toString(kind_) + " "};
3888  for (const auto& arg : args_) {
3889  str += arg->toString();
3890  }
3891  str += ")";
3892  return str;
3893 }
3894 
3895 std::string FunctionOper::toString() const {
3896  std::string str{"(" + name_ + " "};
3897  for (const auto& arg : args_) {
3898  str += arg->toString();
3899  }
3900  str += ")";
3901  return str;
3902 }
3903 
3904 std::shared_ptr<Analyzer::Expr> FunctionOperWithCustomTypeHandling::deep_copy() const {
3905  std::vector<std::shared_ptr<Analyzer::Expr>> args_copy;
3906  for (size_t i = 0; i < getArity(); ++i) {
3907  args_copy.push_back(getArg(i)->deep_copy());
3908  }
3909  return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
3910  type_info, getName(), args_copy);
3911 }
3912 
3914  if (type_info != rhs.get_type_info()) {
3915  return false;
3916  }
3917  const auto rhs_func_oper =
3918  dynamic_cast<const FunctionOperWithCustomTypeHandling*>(&rhs);
3919  if (!rhs_func_oper) {
3920  return false;
3921  }
3922  if (getName() != rhs_func_oper->getName()) {
3923  return false;
3924  }
3925  if (getArity() != rhs_func_oper->getArity()) {
3926  return false;
3927  }
3928  for (size_t i = 0; i < getArity(); ++i) {
3929  if (!(*getArg(i) == *(rhs_func_oper->getArg(i)))) {
3930  return false;
3931  }
3932  }
3933  return true;
3934 }
3935 
3936 double WidthBucketExpr::get_bound_val(const Analyzer::Expr* bound_expr) const {
3937  CHECK(bound_expr);
3938  auto copied_expr = bound_expr->deep_copy();
3939  auto casted_expr = copied_expr->add_cast(SQLTypeInfo(kDOUBLE, false));
3940  CHECK(casted_expr);
3941  auto casted_constant = std::dynamic_pointer_cast<const Analyzer::Constant>(casted_expr);
3942  CHECK(casted_constant);
3943  return casted_constant->get_constval().doubleval;
3944 }
3945 
3947  auto const_partition_count_expr =
3948  dynamic_cast<const Analyzer::Constant*>(partition_count_.get());
3949  if (!const_partition_count_expr) {
3950  return -1;
3951  }
3952  auto d = const_partition_count_expr->get_constval();
3953  switch (const_partition_count_expr->get_type_info().get_type()) {
3954  case kTINYINT:
3955  return d.tinyintval;
3956  case kSMALLINT:
3957  return d.smallintval;
3958  case kINT:
3959  return d.intval;
3960  case kBIGINT: {
3961  auto bi = d.bigintval;
3962  if (bi < 1 || bi > INT32_MAX) {
3963  return -1;
3964  }
3965  return bi;
3966  }
3967  default:
3968  return -1;
3969  }
3970 }
3971 
3972 namespace {
3973 // Assumes lower_bound <= upper_bound
3974 int32_t ordered_bucket(double const lower_bound,
3975  double const upper_bound,
3976  int32_t const partition_count,
3977  double const value) {
3978  if (value < lower_bound) {
3979  return 0;
3980  } else if (upper_bound <= value) {
3981  return partition_count + 1;
3982  } else { // There is no division by 0 since a previous return would have occurred.
3983  double const width = upper_bound - lower_bound;
3984  return static_cast<int32_t>(partition_count * (value - lower_bound) / width) + 1;
3985  }
3986 }
3987 } // namespace
3988 
3989 // this utility function is useful for optimizing expression range decision
3990 // for an expression depending on width_bucket expr
3991 int32_t WidthBucketExpr::compute_bucket(double target_const) const {
3992  if (target_const == inline_fp_null_val(SQLTypeInfo(kDOUBLE))) {
3993  return INT32_MIN;
3994  }
3995  double const lower_bound = get_bound_val(lower_bound_.get());
3996  double const upper_bound = get_bound_val(upper_bound_.get());
3997  int32_t const partition_count = get_partition_count_val();
3998  if (lower_bound <= upper_bound) {
3999  return ordered_bucket(lower_bound, upper_bound, partition_count, target_const);
4000  } else {
4001  return ordered_bucket(-lower_bound, -upper_bound, partition_count, -target_const);
4002  }
4003 }
4004 
4005 namespace {
4006 
4008  CHECK(geo);
4009  switch (geo->getType()) {
4011  return kPOINT;
4012  }
4014  return kMULTIPOINT;
4015  }
4017  return kLINESTRING;
4018  }
4020  return kMULTILINESTRING;
4021  }
4023  return kPOLYGON;
4024  }
4026  return kMULTIPOLYGON;
4027  }
4028  default:
4029  UNREACHABLE();
4030  return kNULLT;
4031  }
4032 }
4033 
4034 } // namespace
4035 
4036 // TODO: fixup null
4037 GeoConstant::GeoConstant(std::unique_ptr<Geospatial::GeoBase>&& geo,
4038  const SQLTypeInfo& ti)
4039  : GeoExpr(ti), geo_(std::move(geo)) {
4040  CHECK(geo_);
4041  if (get_ti_from_geo(geo_.get()) != ti.get_type()) {
4042  throw std::runtime_error("Conflicting types for geo data " + geo_->getWktString() +
4043  " (type provided: " + ti.get_type_name() + ")");
4044  }
4045 }
4046 
4047 std::shared_ptr<Analyzer::Expr> GeoConstant::deep_copy() const {
4048  CHECK(geo_);
4049  return makeExpr<GeoConstant>(geo_->clone(), type_info);
4050 }
4051 
4052 std::string GeoConstant::toString() const {
4053  std::string str{"(GeoConstant "};
4054  CHECK(geo_);
4055  str += geo_->getWktString();
4056  str += ") ";
4057  return str;
4058 }
4059 
4060 std::string GeoConstant::getWKTString() const {
4061  CHECK(geo_);
4062  return geo_->getWktString();
4063 }
4064 
4065 bool GeoConstant::operator==(const Expr& rhs) const {
4066  if (typeid(rhs) != typeid(GeoConstant)) {
4067  return false;
4068  }
4069  const GeoConstant& rhs_c = dynamic_cast<const GeoConstant&>(rhs);
4070  if (type_info != rhs_c.get_type_info() /*|| is_null != rhs_c.get_is_null()*/) {
4071  return false;
4072  }
4073  /* TODO: constant nulls
4074  if (is_null && rhs_c.get_is_null()) {
4075  return true;
4076  }
4077 
4078  */
4079  return *geo_ == *rhs_c.geo_;
4080 }
4081 
4085 }
4086 
4087 std::shared_ptr<Analyzer::Constant> GeoConstant::makePhysicalConstant(
4088  const size_t index) const {
4089  // TODO: handle bounds, etc
4090  const auto num_phys_coords = type_info.get_physical_coord_cols();
4091  CHECK_GE(num_phys_coords, 0);
4092  CHECK_LE(index, size_t(num_phys_coords));
4093  SQLTypeInfo ti = type_info;
4094 
4095  std::vector<double> coords;
4096  std::vector<double> bounds;
4097  std::vector<int> ring_sizes; // also linestring_sizes
4098  std::vector<int> poly_rings;
4099 
4100  const bool validate_with_geos_if_available = false;
4101  bool success =
4103  ti,
4104  coords,
4105  bounds,
4106  ring_sizes,
4107  poly_rings,
4108  validate_with_geos_if_available);
4109  if (!success) {
4110  std::ostringstream oss;
4111  oss << "Failed to create geometry from WKT string: " << geo_->getWktString();
4112  throw std::runtime_error(oss.str());
4113  }
4114 
4115  switch (index) {
4116  case 0: // coords
4117  return Geospatial::convert_coords(coords, ti);
4118  case 1: // ring sizes
4119  return Geospatial::convert_rings(ring_sizes);
4120  case 2: // poly rings
4121  return Geospatial::convert_rings(poly_rings);
4122  default:
4123  UNREACHABLE();
4124  }
4125 
4126  UNREACHABLE();
4127  return nullptr;
4128 }
4129 
4130 std::shared_ptr<Analyzer::Expr> GeoConstant::add_cast(const SQLTypeInfo& new_type_info) {
4131  // TODO: we should eliminate the notion of input and output SRIDs on a type. A type can
4132  // only have 1 SRID. A cast or transforms changes the SRID of the type.
4133  // NOTE: SRID 0 indicates set srid, skip cast
4134  SQLTypeInfo cast_type_info = new_type_info;
4135  if (!(get_type_info().get_input_srid() == 0) &&
4136  (get_type_info().get_input_srid() != new_type_info.get_output_srid())) {
4137  // run cast
4138  CHECK(geo_);
4139  if (!geo_->transform(get_type_info().get_input_srid(),
4140  new_type_info.get_output_srid())) {
4141  throw std::runtime_error("Failed to transform constant geometry: " + toString());
4142  }
4143  // The geo constant has been transformed but the new type info still encodes
4144  // a transform. Need to reset it and eliminate srid transition.
4145  cast_type_info.set_input_srid(new_type_info.get_output_srid());
4146  }
4147  return makeExpr<GeoConstant>(std::move(geo_), cast_type_info);
4148 }
4149 
4151  const std::string& name,
4152  const std::vector<std::shared_ptr<Analyzer::Expr>>& args,
4153  const std::optional<int>& output_srid_override)
4154  : GeoExpr(ti)
4155  , name_(name)
4156  , args_(args)
4157  , output_srid_override_(output_srid_override) {}
4158 
4159 std::shared_ptr<Analyzer::Expr> GeoOperator::deep_copy() const {
4160  std::vector<std::shared_ptr<Analyzer::Expr>> args;
4161  for (size_t i = 0; i < args_.size(); i++) {
4162  args.push_back(args_[i]->deep_copy());
4163  }
4164  return makeExpr<GeoOperator>(type_info, name_, args, output_srid_override_);
4165 }
4166 
4167 void GeoOperator::collect_rte_idx(std::set<int>& rte_idx_set) const {
4168  for (size_t i = 0; i < size(); i++) {
4169  const auto expr = getOperand(i);
4170  expr->collect_rte_idx(rte_idx_set);
4171  }
4172 }
4173 
4175  std::set<const ColumnVar*, bool (*)(const ColumnVar*, const ColumnVar*)>& colvar_set,
4176  bool include_agg) const {
4177  for (size_t i = 0; i < size(); i++) {
4178  const auto expr = getOperand(i);
4179  expr->collect_column_var(colvar_set, include_agg);
4180  }
4181 }
4182 
4183 std::string GeoOperator::toString() const {
4184  std::string str{"(" + name_ + " "};
4185  for (const auto& arg : args_) {
4186  str += arg->toString();
4187  }
4188  str += ")";
4189  return str;
4190 }
4191 
4192 bool GeoOperator::operator==(const Expr& rhs) const {
4193  if (typeid(rhs) != typeid(GeoOperator)) {
4194  return false;
4195  }
4196  const GeoOperator& rhs_go = dynamic_cast<const GeoOperator&>(rhs);
4197  if (getName() != rhs_go.getName()) {
4198  return false;
4199  }
4200  if (rhs_go.size() != size()) {
4201  return false;
4202  }
4203  for (size_t i = 0; i < size(); i++) {
4204  if (args_[i].get() != rhs_go.getOperand(i)) {
4205  return false;
4206  }
4207  }
4208  return true;
4209 }
4210 
4211 size_t GeoOperator::size() const {
4212  return args_.size();
4213 }
4214 
4215 Analyzer::Expr* GeoOperator::getOperand(const size_t index) const {
4216  CHECK_LT(index, args_.size());
4217  return args_[index].get();
4218 }
4219 
4220 std::shared_ptr<Analyzer::Expr> GeoOperator::add_cast(const SQLTypeInfo& new_type_info) {
4221  constexpr bool geo_contains_agg = false;
4222  if (get_type_info().is_geometry()) {
4223  std::vector<std::shared_ptr<Analyzer::Expr>> args;
4224  for (size_t i = 0; i < args_.size(); i++) {
4225  args.push_back(args_[i]->deep_copy());
4226  }
4227  CHECK(new_type_info.is_geometry());
4228  return makeExpr<GeoOperator>(new_type_info, name_, args, output_srid_override_);
4229  } else if (!get_type_info().is_string() && new_type_info.is_string() &&
4230  !new_type_info.is_text_encoding_dict()) {
4231  auto const trans_dict_type = make_transient_dict_type(new_type_info);
4232  return makeExpr<UOper>(trans_dict_type, geo_contains_agg, kCAST, deep_copy());
4233  } else {
4234  return makeExpr<UOper>(new_type_info, geo_contains_agg, kCAST, deep_copy());
4235  }
4236 }
4237 
4238 std::shared_ptr<Analyzer::Expr> GeoTransformOperator::deep_copy() const {
4239  std::vector<std::shared_ptr<Analyzer::Expr>> args;
4240  for (size_t i = 0; i < args_.size(); i++) {
4241  args.push_back(args_[i]->deep_copy());
4242  }
4243  return makeExpr<GeoTransformOperator>(
4245 }
4246 
4247 std::string GeoTransformOperator::toString() const {
4248  std::string str{"(" + name_ + " "};
4249  for (const auto& arg : args_) {
4250  str += arg->toString();
4251  }
4252  str +=
4253  " : " + std::to_string(input_srid_) + " -> " + std::to_string(output_srid_) + " ";
4254  str += ")";
4255  return str;
4256 }
4257 
4258 bool GeoTransformOperator::operator==(const Expr& rhs) const {
4259  if (typeid(rhs) != typeid(GeoTransformOperator)) {
4260  return false;
4261  }
4262  const GeoTransformOperator& rhs_gto = dynamic_cast<const GeoTransformOperator&>(rhs);
4263  if (getName() != rhs_gto.getName()) {
4264  return false;
4265  }
4266  if (rhs_gto.size() != size()) {
4267  return false;
4268  }
4269  for (size_t i = 0; i < size(); i++) {
4270  if (args_[i].get() != rhs_gto.getOperand(i)) {
4271  return false;
4272  }
4273  }
4274  if (input_srid_ != rhs_gto.input_srid_) {
4275  return false;
4276  }
4277  if (output_srid_ != rhs_gto.output_srid_) {
4278  return false;
4279  }
4280  return true;
4281 }
4282 
4284  auto comparator = Analyzer::ColumnVar::colvar_comp;
4285  std::set<const Analyzer::ColumnVar*,
4286  bool (*)(const Analyzer::ColumnVar*, const Analyzer::ColumnVar*)>
4287  colvar_set(comparator);
4288  collect_column_var(colvar_set, true);
4289  if (colvar_set.size() != 1UL) {
4290  return false;
4291  }
4292  auto col_expr_ptr = *colvar_set.begin();
4293  CHECK(col_expr_ptr);
4294  return col_expr_ptr->get_type_info().is_dict_encoded_string();
4295 }
4296 
4297 std::vector<size_t> StringOper::getLiteralArgIndexes() const {
4298  std::vector<size_t> literal_arg_indexes;
4299  const auto num_args = args_.size();
4300  for (size_t idx = 0; idx < num_args; ++idx) {
4301  if (dynamic_cast<const Constant*>(args_[idx].get())) {
4302  literal_arg_indexes.emplace_back(idx);
4303  }
4304  }
4305  return literal_arg_indexes;
4306 }
4307 
4308 using LiteralArgMap = std::map<size_t, std::pair<SQLTypes, Datum>>;
4309 
4311  LiteralArgMap literal_arg_map;
4312  const auto num_args = getArity();
4313  for (size_t idx = 0; idx < num_args; ++idx) {
4314  const auto constant_arg_expr = dynamic_cast<const Analyzer::Constant*>(getArg(idx));
4315  if (constant_arg_expr) {
4316  literal_arg_map.emplace(
4317  std::make_pair(idx,
4318  std::make_pair(constant_arg_expr->get_type_info().get_type(),
4319  constant_arg_expr->get_constval())));
4320  }
4321  }
4322  return literal_arg_map;
4323 }
4324 
4326  const SqlStringOpKind kind,
4327  const std::vector<std::shared_ptr<Analyzer::Expr>>& args) {
4329  << "get_return_type for TRY_STRING_CAST disallowed.";
4330  SQLTypeInfo return_ti(kNULLT);
4331  size_t num_var_string_inputs{0};
4332  for (const auto& arg : args) {
4333  const auto raw_arg = arg.get();
4334  const auto& arg_ti = arg->get_type_info();
4335  if (dynamic_cast<const Analyzer::CaseExpr*>(remove_cast(raw_arg))) {
4336  // Currently we disallow case statement inputs to string functions
4337  // pending a full resolution to QE-359, but the error is thrown
4338  // downstream in StringOper::check_operand_types
4339  return SQLTypeInfo(kTEXT, kENCODING_DICT, 0, kNULLT);
4340  } else if (arg_ti.is_string() && dynamic_cast<const Analyzer::Constant*>(raw_arg)) {
4341  if (return_ti == SQLTypeInfo(kNULLT)) {
4342  return_ti = arg_ti;
4343  }
4344  } else if (arg_ti.is_none_encoded_string()) {
4345  return SQLTypeInfo(kTEXT, kENCODING_DICT, 0, kNULLT);
4346  } else if (arg_ti.is_dict_encoded_string()) {
4347  if (arg_ti.getStringDictKey().isTransientDict()) {
4348  return SQLTypeInfo(kTEXT, kENCODING_DICT, 0, kNULLT);
4349  } else {
4350  num_var_string_inputs++;
4351  return_ti = arg_ti;
4352  }
4353  }
4354  }
4355  if (num_var_string_inputs > 1UL) {
4356  return SQLTypeInfo(kTEXT, kENCODING_DICT, 0, kNULLT);
4357  }
4358  return return_ti;
4359 }
4360 
4362  const size_t min_args,
4363  const std::vector<OperandTypeFamily>& expected_type_families,
4364  const std::vector<std::string>& arg_names,
4365  const bool dict_encoded_cols_only,
4366  const bool cols_first_arg_only) const {
4367  std::ostringstream oss;
4369  oss << "Function " << ::toString(get_kind()) << " not supported.";
4370  throw std::runtime_error(oss.str());
4371  }
4372  const size_t num_args = args_.size();
4373  CHECK_EQ(expected_type_families.size(), arg_names.size());
4374  if (num_args < min_args || num_args > expected_type_families.size()) {
4375  oss << "Error instantiating " << ::toString(get_kind()) << " operator. ";
4376  oss << "Expected " << expected_type_families.size() << " arguments, but received "
4377  << num_args << ".";
4378  }
4379  for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
4380  const auto& expected_type_family = expected_type_families[arg_idx];
4381  // We need to remove any casts that Calcite may add to try the right operand type,
4382  // even if we don't support them. Need to check how this works with casts we do
4383  // support.
4384  auto arg_ti = args_[arg_idx]->get_type_info();
4385  const auto decasted_arg = remove_cast(args_[arg_idx]);
4386  const bool is_arg_case =
4387  dynamic_cast<const Analyzer::CaseExpr*>(decasted_arg.get()) != nullptr;
4388  if (is_arg_case) {
4389  oss << "Error instantiating " << ::toString(get_kind()) << " operator. "
4390  << "Currently string operations cannot be run on output of a case "
4391  << "statement.";
4392  throw std::runtime_error(oss.str());
4393  }
4394  const bool is_arg_constant =
4395  dynamic_cast<const Analyzer::Constant*>(decasted_arg.get()) != nullptr;
4396  auto decasted_arg_ti = decasted_arg->get_type_info();
4397  // We need to prevent any non-string type from being casted to a string, but can
4398  // permit non-integer types being casted to integers Todo: Find a cleaner way to
4399  // handle this (we haven't validated any of the casts that calcite has given us at
4400  // the point of RelAlgTranslation)
4401  if (arg_ti != decasted_arg_ti &&
4402  (arg_ti.is_integer() && decasted_arg_ti.is_string())) {
4403  arg_ti = decasted_arg_ti;
4404  }
4405 
4406  if (cols_first_arg_only && !is_arg_constant && arg_idx >= 1UL) {
4407  oss << "Error instantiating " << ::toString(get_kind()) << " operator. "
4408  << "Currently only column inputs are allowed for argument '" << arg_names[0]
4409  << "', but a column input was received for argument '" << arg_names[arg_idx]
4410  << "'.";
4411  throw std::runtime_error(oss.str());
4412  }
4413  switch (expected_type_family) {
4415  if (!arg_ti.is_string()) {
4416  oss << "Error instantiating " << ::toString(get_kind()) << " operator. "
4417  << "Expected text type for argument '" << arg_names[arg_idx] << "'";
4418  throw std::runtime_error(oss.str());
4419  break;
4420  }
4421  if (dict_encoded_cols_only &&
4422  (!is_arg_constant && !arg_ti.is_dict_encoded_string())) {
4423  oss << "Error instantiating " << ::toString(get_kind()) << " operator. "
4424  << "Currently only text-encoded dictionary-encoded column inputs are "
4425  << "allowed, but a none-encoded text column argument was received.";
4426  throw std::runtime_error(oss.str());
4427  break;
4428  }
4429  break;
4430  }
4432  if (!IS_INTEGER(arg_ti.get_type())) {
4433  oss << "Error instantiating " << ::toString(get_kind()) << " operator. "
4434  << "Expected integer type for argument " << arg_idx + 1 << " ('"
4435  << arg_names[arg_idx] << "').";
4436  throw std::runtime_error(oss.str());
4437  break;
4438  }
4439  if (!is_arg_constant) {
4440  oss << "Error instantiating " << ::toString(get_kind()) << " operator. "
4441  << "Currently only text-encoded dictionary column inputs are "
4442  << "allowed, but an integer-type column was provided.";
4443  throw std::runtime_error(oss.str());
4444  break;
4445  }
4446  break;
4447  }
4448  }
4449  }
4450 }
4451 
4453  const std::vector<std::shared_ptr<Analyzer::Expr>>& operands) {
4454  if (operands.size() != 2UL) {
4455  std::ostringstream oss;
4456  oss << "Concat operator expects two arguments, but was provided " << operands.size()
4457  << ".";
4458  throw std::runtime_error(oss.str());
4459  }
4460  const auto operand0_is_literal =
4461  dynamic_cast<const Analyzer::Constant*>(operands[0].get());
4462  const auto operand1_is_literal =
4463  dynamic_cast<const Analyzer::Constant*>(operands[1].get());
4464  if (operand0_is_literal && !operand1_is_literal) {
4465  return SqlStringOpKind::RCONCAT;
4466  }
4467  return SqlStringOpKind::CONCAT;
4468 }
4469 
4470 std::vector<std::shared_ptr<Analyzer::Expr>> ConcatStringOper::normalize_operands(
4471  const std::vector<std::shared_ptr<Analyzer::Expr>>& operands) {
4473  CHECK_EQ(operands.size(), 2UL); // Size should be 2 per get_concat_ordered_kind
4474  return {operands[1], operands[0]};
4475  }
4476  return operands;
4477 }
4478 
4480  const SqlStringOpKind pad_op_kind) {
4481  if (!(pad_op_kind == SqlStringOpKind::LPAD || pad_op_kind == SqlStringOpKind::RPAD)) {
4482  // Arguably should CHECK here
4483  throw std::runtime_error("Invalid pad type supplied to PAD operator");
4484  }
4485  return pad_op_kind;
4486 }
4487 
4489  const SqlStringOpKind trim_op_kind_maybe,
4490  const std::vector<std::shared_ptr<Analyzer::Expr>>& args) {
4491  auto get_trim_type_if_exists = [&args]() {
4492  if (args.empty()) {
4493  return SqlStringOpKind::INVALID;
4494  }
4495  const auto trim_type_arg = dynamic_cast<const Analyzer::Constant*>(args[0].get());
4496  if (!trim_type_arg) {
4497  return SqlStringOpKind::INVALID;
4498  }
4499  const auto trim_type_str = to_upper(*trim_type_arg->get_constval().stringval);
4500  if (trim_type_str == "BOTH") {
4501  return SqlStringOpKind::TRIM;
4502  }
4503  if (trim_type_str == "LEADING") {
4504  return SqlStringOpKind::LTRIM;
4505  }
4506  if (trim_type_str == "TRAILING") {
4507  return SqlStringOpKind::RTRIM;
4508  }
4509  return SqlStringOpKind::INVALID;
4510  };
4511 
4512  const auto trim_op_kind = trim_op_kind_maybe == SqlStringOpKind::TRIM
4513  ? get_trim_type_if_exists()
4514  : trim_op_kind_maybe;
4516  return trim_op_kind;
4517 }
4518 
4519 std::vector<std::shared_ptr<Analyzer::Expr>> TrimStringOper::normalize_operands(
4520  const std::vector<std::shared_ptr<Analyzer::Expr>>& operands,
4521  const SqlStringOpKind string_op_kind) {
4522  if (operands.size() < 2UL) {
4523  throw std::runtime_error("Trim operator expects 2 arguments.");
4524  }
4525 
4526  // Calcite is returning LTRIM/RTRIM(string_literal1, string_literal2) with the
4527  // arguments in that order, but LTRIM/TRIM(string_var, string_literal) in the
4528  // reverse order that the main TRIM operator uses as well
4529  // Until we can look into that more, reverse order only if we have a const then
4530  // non-const input order
4531 
4532  if (string_op_kind == SqlStringOpKind::LTRIM ||
4533  string_op_kind == SqlStringOpKind::RTRIM) {
4534  CHECK_EQ(operands.size(), 2UL);
4535  if (dynamic_cast<const Analyzer::Constant*>(operands[0].get()) &&
4536  !dynamic_cast<const Analyzer::Constant*>(operands[1].get())) {
4537  return {operands[1], operands[0]};
4538  }
4539  return operands;
4540  }
4541  CHECK_EQ(operands.size(), 3UL);
4542  return {operands[2], operands[1]};
4543 }
4544 
4545 std::vector<std::shared_ptr<Analyzer::Expr>> PositionStringOper::normalize_operands(
4546  const std::vector<std::shared_ptr<Analyzer::Expr>>& operands) {
4547  CHECK_GE(operands.size(), 2UL);
4548  CHECK_LE(operands.size(), 3UL);
4549  std::vector<std::shared_ptr<Analyzer::Expr>> normalized_operands;
4550  normalized_operands.emplace_back(operands[1]);
4551  normalized_operands.emplace_back(operands[0]);
4552  if (operands.size() == 3UL) {
4553  normalized_operands.emplace_back(operands[2]);
4554  }
4555  return normalized_operands;
4556 }
4557 
4558 std::vector<std::shared_ptr<Analyzer::Expr>>
4560  const std::vector<std::shared_ptr<Analyzer::Expr>>& operands) {
4561  if (operands.size() != 2UL) {
4562  std::ostringstream oss;
4563  oss << "JAROWINKLER_SIMILARITY operator expects two arguments, but was provided "
4564  << operands.size() << ".";
4565  throw std::runtime_error(oss.str());
4566  }
4567  const auto operand0_is_literal =
4568  dynamic_cast<const Analyzer::Constant*>(operands[0].get());
4569  const auto operand1_is_literal =
4570  dynamic_cast<const Analyzer::Constant*>(operands[1].get());
4571  if (operand0_is_literal && !operand1_is_literal) {
4572  return {operands[1], operands[0]};
4573  }
4574  return operands;
4575 }
4576 
4577 std::vector<std::shared_ptr<Analyzer::Expr>>
4579  const std::vector<std::shared_ptr<Analyzer::Expr>>& operands) {
4580  if (operands.size() != 2UL) {
4581  std::ostringstream oss;
4582  oss << "LEVENSHTEIN_DISTANCE operator expects two arguments, but was provided "
4583  << operands.size() << ".";
4584  throw std::runtime_error(oss.str());
4585  }
4586  const auto operand0_is_literal =
4587  dynamic_cast<const Analyzer::Constant*>(operands[0].get());
4588  const auto operand1_is_literal =
4589  dynamic_cast<const Analyzer::Constant*>(operands[1].get());
4590  if (operand0_is_literal && !operand1_is_literal) {
4591  return {operands[1], operands[0]};
4592  }
4593  return operands;
4594 }
4595 
4596 } // namespace Analyzer
4597 
4598 bool expr_list_match(const std::vector<std::shared_ptr<Analyzer::Expr>>& lhs,
4599  const std::vector<std::shared_ptr<Analyzer::Expr>>& rhs) {
4600  if (lhs.size() != rhs.size()) {
4601  return false;
4602  }
4603  for (size_t i = 0; i < lhs.size(); ++i) {
4604  if (!(*lhs[i] == *rhs[i])) {
4605  return false;
4606  }
4607  }
4608  return true;
4609 }
4610 
4611 std::shared_ptr<Analyzer::Expr> remove_cast(const std::shared_ptr<Analyzer::Expr>& expr) {
4612  const auto uoper = dynamic_cast<const Analyzer::UOper*>(expr.get());
4613  if (!uoper || uoper->get_optype() != kCAST) {
4614  return expr;
4615  }
4616  return uoper->get_own_operand();
4617 }
4618 
4620  const auto uoper = dynamic_cast<const Analyzer::UOper*>(expr);
4621  if (!uoper || uoper->get_optype() != kCAST) {
4622  return expr;
4623  }
4624  return uoper->get_operand();
4625 }
DEVICE auto upper_bound(ARGS &&...args)
Definition: gpu_enabled.h:123
std::shared_ptr< Analyzer::Expr > arg
Definition: Analyzer.h:1302
int8_t tinyintval
Definition: Datum.h:73
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3904
std::shared_ptr< Analyzer::Expr > arg
Definition: Analyzer.h:1174
Query * next_query
Definition: Analyzer.h:3205
Defines data structures for the semantic analysis phase of query processing.
InIntegerSet(const std::shared_ptr< const Analyzer::Expr > a, const std::vector< int64_t > &values, const bool not_null)
Definition: Analyzer.cpp:1706
Definition: sqldefs.h:74
std::shared_ptr< Analyzer::Expr > rewrite_agg_to_var(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2085
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:392
void set_compression(EncodingType c)
Definition: sqltypes.h:481
T roundDecimal(int64_t n, unsigned scale)
Definition: Analyzer.cpp:855
std::string toString() const override
Definition: Analyzer.cpp:3000
Query * parsetree
Definition: Analyzer.h:632
double power10(unsigned const x)
Definition: misc.h:284
float get_likelihood() const
Definition: Analyzer.h:1269
static constexpr int32_t kMaxRepresentableNumericPrecision
Definition: sqltypes.h:60
#define CHECK_EQ(x, y)
Definition: Logger.h:301
std::shared_ptr< Analyzer::Expr > rewrite_agg_to_var(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2234
std::shared_ptr< Analyzer::Expr > expr
Definition: Analyzer.h:3124
std::string toString() const override
Definition: Analyzer.cpp:2922
void find_expr(std::function< bool(const Expr *)> f, std::list< const Expr * > &expr_list) const override
Definition: Analyzer.cpp:3300
bool unnest
Definition: Analyzer.h:3125
void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const override
Definition: Analyzer.cpp:1692
InValues(std::shared_ptr< Analyzer::Expr > a, const std::list< std::shared_ptr< Analyzer::Expr >> &l)
Definition: Analyzer.cpp:1688
const Expr * get_from_expr() const
Definition: Analyzer.h:1432
static bool simple_predicate_has_simple_cast(const std::shared_ptr< Analyzer::Expr > cast_operand, const std::shared_ptr< Analyzer::Expr > const_operand)
Definition: Analyzer.cpp:1553
#define IS_LOGIC(X)
Definition: sqldefs.h:64
const Expr * get_partition_count() const
Definition: Analyzer.h:1201
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3769
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2617
std::string toString() const override
Definition: Analyzer.cpp:2724
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3819
#define NULL_DOUBLE
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3799
GeoConstant(std::unique_ptr< Geospatial::GeoBase > &&geo, const SQLTypeInfo &ti)
Definition: Analyzer.cpp:4037
void get_domain(DomainSet &domain_set) const override
Definition: Analyzer.cpp:3625
std::shared_ptr< Analyzer::Expr > rewrite_agg_to_var(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2256
std::string toString() const final
Definition: Analyzer.cpp:4052
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2359
const Expr * get_else_expr() const
Definition: Analyzer.h:1387
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3699
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2505
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3794
static std::vector< std::shared_ptr< Analyzer::Expr > > normalize_operands(const std::vector< std::shared_ptr< Analyzer::Expr >> &operands)
Definition: Analyzer.cpp:4545
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:256
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:3864
bool Datum_equal(const SQLTypeInfo &ti, Datum val1, Datum val2)
Definition: Analyzer.cpp:2291
std::string DatumToString(Datum d, const SQLTypeInfo &ti)
Definition: Datum.cpp:460
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2351
void check_operand_types(const size_t min_args, const std::vector< OperandTypeFamily > &expected_type_families, const std::vector< std::string > &arg_names, const bool dict_encoded_cols_only=false, const bool cols_first_arg_only=true) const
Definition: Analyzer.cpp:4361
const Expr * get_escape_expr() const
Definition: Analyzer.h:1064
std::shared_ptr< Analyzer::Expr > arg
Definition: Analyzer.h:950
void find_expr(std::function< bool(const Expr *)> f, std::list< const Expr * > &expr_list) const override
Definition: Analyzer.cpp:3311
std::shared_ptr< Analyzer::Expr > rewrite_with_targetlist(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2163
std::shared_ptr< Analyzer::Expr > decompress()
Definition: Analyzer.cpp:749
size_t getArity() const
Definition: Analyzer.h:2746
std::optional< int > output_srid_override_
Definition: Analyzer.h:3320
Definition: sqltypes.h:76
std::shared_ptr< Analyzer::Expr > remove_cast(const std::shared_ptr< Analyzer::Expr > &expr)
Definition: Analyzer.cpp:4611
bool is_null_value(const SQLTypeInfo &ti, const Datum &constval)
Definition: Analyzer.cpp:1233
static bool colvar_comp(const ColumnVar *l, const ColumnVar *r)
Definition: Analyzer.h:215
SQLTypes
Definition: sqltypes.h:65
const std::shared_ptr< Analyzer::Expr > frame_end_bound_
Definition: Analyzer.h:3000
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3784
void add_rte(RangeTableEntry *rte)
Definition: Analyzer.cpp:1506
bool is_timestamp() const
Definition: sqltypes.h:1046
std::shared_ptr< Analyzer::Expr > operand
Definition: Analyzer.h:424
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3734
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2413
std::shared_ptr< Analyzer::Expr > arg
Definition: Analyzer.h:904
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3809
std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr > > > expr_pair_list
Definition: Analyzer.h:1414
void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const override
Definition: Analyzer.cpp:1905
std::shared_ptr< Analyzer::Expr > rewrite_agg_to_var(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2220
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2634
#define NULL_FLOAT
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3684
void find_expr(std::function< bool(const Expr *)> f, std::list< const Expr * > &expr_list) const override
Definition: Analyzer.cpp:3320
void collect_rte_idx(std::set< int > &rte_idx_set) const final
Definition: Analyzer.cpp:4167
std::shared_ptr< Analyzer::Expr > rewrite_with_child_targetlist(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2206
bool operator==(const Expr &rhs) const override
Definition: Analyzer.cpp:2457
void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const override
Definition: Analyzer.cpp:1628
#define NULL_BIGINT
virtual void add_unique(std::list< const Expr * > &expr_list) const
Definition: Analyzer.cpp:3248
std::shared_ptr< Analyzer::Expr > right_operand
Definition: Analyzer.h:530
void find_expr(std::function< bool(const Expr *)> f, std::list< const Expr * > &expr_list) const override
Definition: Analyzer.cpp:3349
std::shared_ptr< Analyzer::Expr > escape_expr
Definition: Analyzer.h:1178
bool operator==(Expr const &rhs) const override
Definition: Analyzer.cpp:2669
ExtractField get_field() const
Definition: Analyzer.h:1431
std::shared_ptr< Analyzer::Expr > rewrite_agg_to_var(const std::vector< std::shared_ptr< TargetEntry >> &tlist) const override
Definition: Analyzer.cpp:2026
void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const override
Definition: Analyzer.cpp:1725
void collect_rte_idx(std::set< int > &rte_idx_set) const override
Definition: Analyzer.cpp:3515
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:157
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:102
void collect_column_var(std::set< const ColumnVar *, bool(*)(const ColumnVar *, const ColumnVar *)> &colvar_set, bool include_agg) const override
Definition: Analyzer.cpp:3583
bool is_fp() const
Definition: sqltypes.h:573
const Expr * get_escape_expr() const
Definition: Analyzer.h:1136
HOST DEVICE int get_scale() const
Definition: sqltypes.h:396
const Expr * get_right_operand() const
Definition: Analyzer.h:456
SQLOps
Definition: sqldefs.h:31
void group_predicates(std::list< const Expr * > &scan_predicates, std::list< const Expr * > &join_predicates, std::list< const Expr * > &const_predicates) const override
Definition: Analyzer.cpp:1871
void collect_rte_idx(std::set< int > &rte_idx_set) const override
Definition: Analyzer.cpp:3494
std::string toString() const override
Definition: Analyzer.cpp:3196
shared::ColumnKey column_key_
Definition: Analyzer.h:239
Definition: sqldefs.h:37
std::map< size_t, std::pair< SQLTypes, Datum >> LiteralArgMap
Definition: Analyzer.h:1769
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:3749
SqlWindowFrameBoundType bound_type_
Definition: Analyzer.h:2852
void find_expr(std::function< bool(const Expr *)> f, std::list< const Expr * > &expr_list) const override
Definition: Analyzer.cpp:3450
int8_t boolval
Definition: Datum.h:72
std::string get_compression_name() const
Definition: sqltypes.h:522
DEVICE int64_t DateTruncate(DatetruncField field, const int64_t timeval)