OmniSciDB  ba1bac9284
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RelAlgTranslator Class Reference

#include <RelAlgTranslator.h>

+ Collaboration diagram for RelAlgTranslator:

Public Member Functions

 RelAlgTranslator (const Catalog_Namespace::Catalog &cat, std::shared_ptr< const query_state::QueryState > q_s, const Executor *executor, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< JoinType > &join_types, const time_t now, const bool just_explain)
 
std::shared_ptr< Analyzer::ExprtranslateScalarRex (const RexScalar *rex) const
 
bool generated_geos_ops ()
 

Static Public Member Functions

static std::shared_ptr
< Analyzer::Expr
translateAggregateRex (const RexAgg *rex, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
 
static std::shared_ptr
< Analyzer::Expr
translateLiteral (const RexLiteral *)
 

Private Member Functions

std::shared_ptr< Analyzer::ExprtranslateScalarSubquery (const RexSubQuery *) const
 
std::shared_ptr< Analyzer::ExprtranslateInput (const RexInput *) const
 
std::shared_ptr< Analyzer::ExprtranslateUoper (const RexOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateInOper (const RexOperator *) const
 
std::shared_ptr< Analyzer::ExprgetInIntegerSetExpr (std::shared_ptr< Analyzer::Expr > arg, const ResultSet &val_set) const
 
std::shared_ptr< Analyzer::ExprtranslateOper (const RexOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateOverlapsOper (const RexOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateCase (const RexCase *) const
 
std::shared_ptr< Analyzer::ExprtranslateLike (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateRegexp (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateLikely (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateUnlikely (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateExtract (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateDateadd (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateDatePlusMinus (const RexOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateDatediff (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateDatepart (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateLength (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateKeyForString (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateSampleRatio (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateCurrentUser (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateLower (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateCardinality (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateItem (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateCurrentDate () const
 
std::shared_ptr< Analyzer::ExprtranslateCurrentTime () const
 
std::shared_ptr< Analyzer::ExprtranslateCurrentTimestamp () const
 
std::shared_ptr< Analyzer::ExprtranslateDatetime (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateHPTLiteral (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateAbs (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateSign (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateOffsetInFragment () const
 
std::shared_ptr< Analyzer::ExprtranslateArrayFunction (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateFunction (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateWindowFunction (const RexWindowFunctionOperator *) const
 
Analyzer::ExpressionPtrVector translateFunctionArgs (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateUnaryGeoFunction (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateBinaryGeoFunction (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateTernaryGeoFunction (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateFunctionWithGeoArg (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateGeoComparison (const RexOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateGeoProjection (const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
 
std::shared_ptr< Analyzer::ExprtranslateGeoPredicate (const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
 
std::shared_ptr< Analyzer::ExprtranslateGeoBinaryConstructor (const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
 
std::shared_ptr< Analyzer::ExprtranslateGeoOverlapsOper (const RexOperator *) const
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
translateGeoFunctionArg (const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
translateGeoColumn (const RexInput *, SQLTypeInfo &, const bool with_bounds, const bool with_render_group, const bool expand_geo_col) const
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
translateGeoLiteral (const RexLiteral *, SQLTypeInfo &, bool) const
 

Private Attributes

const Catalog_Namespace::Catalogcat_
 
std::shared_ptr< const
query_state::QueryState
query_state_
 
const Executorexecutor_
 
const std::unordered_map
< const RelAlgNode *, int > 
input_to_nest_level_
 
const std::vector< JoinTypejoin_types_
 
time_t now_
 
bool generated_geos_ops_
 
const bool just_explain_
 

Detailed Description

Definition at line 47 of file RelAlgTranslator.h.

Constructor & Destructor Documentation

RelAlgTranslator::RelAlgTranslator ( const Catalog_Namespace::Catalog cat,
std::shared_ptr< const query_state::QueryState q_s,
const Executor executor,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
const std::vector< JoinType > &  join_types,
const time_t  now,
const bool  just_explain 
)
inline

Definition at line 49 of file RelAlgTranslator.h.

56  : cat_(cat)
57  , query_state_(q_s)
58  , executor_(executor)
59  , input_to_nest_level_(input_to_nest_level)
60  , join_types_(join_types)
61  , now_(now)
62  , generated_geos_ops_(false)
63  , just_explain_(just_explain) {}
const std::vector< JoinType > join_types_
const Executor * executor_
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
std::shared_ptr< const query_state::QueryState > query_state_
const bool just_explain_
const Catalog_Namespace::Catalog & cat_

Member Function Documentation

bool RelAlgTranslator::generated_geos_ops ( )
inline

Definition at line 73 of file RelAlgTranslator.h.

References generated_geos_ops_.

73 { return generated_geos_ops_; }
std::shared_ptr< Analyzer::Expr > RelAlgTranslator::getInIntegerSetExpr ( std::shared_ptr< Analyzer::Expr arg,
const ResultSet val_set 
) const
private

Definition at line 767 of file RelAlgTranslator.cpp.

References result_set::can_use_parallel_algorithms(), cat_, CHECK, CHECK_EQ, CHECK_GE, cpu_threads(), executor_, anonymous_namespace{RelAlgTranslator.cpp}::fill_dictionary_encoded_in_vals(), anonymous_namespace{RelAlgTranslator.cpp}::fill_integer_in_vals(), g_cluster, Catalog_Namespace::Catalog::getDatabaseId(), Catalog_Namespace::Catalog::getStringDictionaryHosts(), i, inline_int_null_val(), and kENCODING_DICT.

Referenced by translateInOper().

769  {
771  return nullptr;
772  }
773  std::vector<int64_t> value_exprs;
774  const size_t fetcher_count = cpu_threads();
775  std::vector<std::vector<int64_t>> expr_set(fetcher_count);
776  std::vector<std::future<void>> fetcher_threads;
777  const auto& arg_type = arg->get_type_info();
778  const auto entry_count = val_set.entryCount();
779  CHECK_EQ(size_t(1), val_set.colCount());
780  const auto& col_type = val_set.getColType(0);
781  if (g_cluster && arg_type.is_string() &&
782  (col_type.get_comp_param() <= 0 || arg_type.get_comp_param() <= 0)) {
783  // Skip this case for now, see comment for fill_dictionary_encoded_in_vals.
784  return nullptr;
785  }
786  std::atomic<size_t> total_in_vals_count{0};
787  for (size_t i = 0,
788  start_entry = 0,
789  stride = (entry_count + fetcher_count - 1) / fetcher_count;
790  i < fetcher_count && start_entry < entry_count;
791  ++i, start_entry += stride) {
792  expr_set[i].reserve(entry_count / fetcher_count);
793  const auto end_entry = std::min(start_entry + stride, entry_count);
794  if (arg_type.is_string()) {
795  CHECK_EQ(kENCODING_DICT, arg_type.get_compression());
796  // const int32_t dest_dict_id = arg_type.get_comp_param();
797  // const int32_t source_dict_id = col_type.get_comp_param();
798  const DictRef dest_dict_ref(arg_type.get_comp_param(), cat_.getDatabaseId());
799  const DictRef source_dict_ref(col_type.get_comp_param(), cat_.getDatabaseId());
800  const auto dd = executor_->getStringDictionaryProxy(
801  arg_type.get_comp_param(), val_set.getRowSetMemOwner(), true);
802  const auto sd = executor_->getStringDictionaryProxy(
803  col_type.get_comp_param(), val_set.getRowSetMemOwner(), true);
804  CHECK(sd);
805  const auto needle_null_val = inline_int_null_val(arg_type);
806  fetcher_threads.push_back(std::async(
807  std::launch::async,
808  [this,
809  &val_set,
810  &total_in_vals_count,
811  sd,
812  dd,
813  source_dict_ref,
814  dest_dict_ref,
815  needle_null_val](
816  std::vector<int64_t>& in_vals, const size_t start, const size_t end) {
817  if (g_cluster) {
818  CHECK_GE(dd->getGeneration(), 0);
820  total_in_vals_count,
821  &val_set,
822  {start, end},
824  source_dict_ref,
825  dest_dict_ref,
826  dd->getGeneration(),
827  needle_null_val);
828  } else {
830  total_in_vals_count,
831  &val_set,
832  {start, end},
833  sd,
834  dd,
835  needle_null_val);
836  }
837  },
838  std::ref(expr_set[i]),
839  start_entry,
840  end_entry));
841  } else {
842  CHECK(arg_type.is_integer());
843  fetcher_threads.push_back(std::async(
844  std::launch::async,
845  [&val_set, &total_in_vals_count](
846  std::vector<int64_t>& in_vals, const size_t start, const size_t end) {
847  fill_integer_in_vals(in_vals, total_in_vals_count, &val_set, {start, end});
848  },
849  std::ref(expr_set[i]),
850  start_entry,
851  end_entry));
852  }
853  }
854  for (auto& child : fetcher_threads) {
855  child.get();
856  }
857 
858  val_set.moveToBegin();
859  value_exprs.reserve(entry_count);
860  for (auto& exprs : expr_set) {
861  value_exprs.insert(value_exprs.end(), exprs.begin(), exprs.end());
862  }
863  return makeExpr<Analyzer::InIntegerSet>(
864  arg, value_exprs, arg_type.get_notnull() && col_type.get_notnull());
865 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
const Executor * executor_
#define CHECK_GE(x, y)
Definition: Logger.h:219
void fill_dictionary_encoded_in_vals(std::vector< int64_t > &in_vals, std::atomic< size_t > &total_in_vals_count, const ResultSet *values_rowset, const std::pair< int64_t, int64_t > values_rowset_slice, const StringDictionaryProxy *source_dict, const StringDictionaryProxy *dest_dict, const int64_t needle_null_val)
int getDatabaseId() const
Definition: Catalog.h:277
const std::vector< LeafHostInfo > & getStringDictionaryHosts() const
Definition: Catalog.cpp:1543
#define CHECK(condition)
Definition: Logger.h:206
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool g_cluster
int cpu_threads()
Definition: thread_count.h:24
bool can_use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1118
void fill_integer_in_vals(std::vector< int64_t > &in_vals, std::atomic< size_t > &total_in_vals_count, const ResultSet *values_rowset, const std::pair< int64_t, int64_t > values_rowset_slice)
const Catalog_Namespace::Catalog & cat_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateAbs ( const RexFunctionOperator rex_function) const
private

Definition at line 1315 of file RelAlgTranslator.cpp.

References CHECK, CHECK_EQ, RexOperator::getOperand(), kBOOLEAN, kLT, kONE, kUMINUS, anonymous_namespace{RelAlgTranslator.cpp}::makeNumericConstant(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

1316  {
1317  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1318  expr_list;
1319  CHECK_EQ(size_t(1), rex_function->size());
1320  const auto operand = translateScalarRex(rex_function->getOperand(0));
1321  const auto& operand_ti = operand->get_type_info();
1322  CHECK(operand_ti.is_number());
1323  const auto zero = makeNumericConstant(operand_ti, 0);
1324  const auto lt_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kLT, kONE, operand, zero);
1325  const auto uminus_operand =
1326  makeExpr<Analyzer::UOper>(operand_ti.get_type(), kUMINUS, operand);
1327  expr_list.emplace_back(lt_zero, uminus_operand);
1328  return makeExpr<Analyzer::CaseExpr>(operand_ti, false, expr_list, operand);
1329 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< Analyzer::Constant > makeNumericConstant(const SQLTypeInfo &ti, const long val)
Definition: sqldefs.h:69
#define CHECK(condition)
Definition: Logger.h:206
Definition: sqldefs.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateAggregateRex ( const RexAgg rex,
const std::vector< std::shared_ptr< Analyzer::Expr >> &  scalar_sources 
)
static

Definition at line 225 of file RelAlgTranslator.cpp.

References CHECK_LE, CHECK_LT, g_cluster, get_agg_type(), RexAgg::getKind(), RexAgg::getOperand(), anonymous_namespace{RelAlgTranslator.cpp}::is_agg_supported_for_type(), anonymous_namespace{RelAlgOptimizer.cpp}::is_distinct(), RexAgg::isDistinct(), kAPPROX_COUNT_DISTINCT, kAPPROX_MEDIAN, kINT, RexAgg::size(), and ThriftSerializers::takes_arg().

Referenced by anonymous_namespace{RelAlgExecutor.cpp}::translate_targets().

227  {
228  const auto agg_kind = rex->getKind();
229  const bool is_distinct = rex->isDistinct();
230  const bool takes_arg{rex->size() > 0};
231  std::shared_ptr<Analyzer::Expr> arg_expr;
232  std::shared_ptr<Analyzer::Constant> err_rate;
233  if (takes_arg) {
234  const auto operand = rex->getOperand(0);
235  CHECK_LT(operand, scalar_sources.size());
236  CHECK_LE(rex->size(), 2u);
237  arg_expr = scalar_sources[operand];
238  if (agg_kind == kAPPROX_COUNT_DISTINCT && rex->size() == 2) {
239  err_rate = std::dynamic_pointer_cast<Analyzer::Constant>(
240  scalar_sources[rex->getOperand(1)]);
241  if (!err_rate || err_rate->get_type_info().get_type() != kINT ||
242  err_rate->get_constval().intval < 1 || err_rate->get_constval().intval > 100) {
243  throw std::runtime_error(
244  "APPROX_COUNT_DISTINCT's second parameter should be SMALLINT literal between "
245  "1 and 100");
246  }
247  }
248  if (g_cluster && agg_kind == kAPPROX_MEDIAN) {
249  throw std::runtime_error(
250  "APPROX_MEDIAN is not supported in distributed mode at this time.");
251  }
252  const auto& arg_ti = arg_expr->get_type_info();
253  if (!is_agg_supported_for_type(agg_kind, arg_ti)) {
254  throw std::runtime_error("Aggregate on " + arg_ti.get_type_name() +
255  " is not supported yet.");
256  }
257  }
258  const auto agg_ti = get_agg_type(agg_kind, arg_expr.get());
259  return makeExpr<Analyzer::AggExpr>(agg_ti, agg_kind, arg_expr, is_distinct, err_rate);
260 }
SQLAgg getKind() const
size_t getOperand(size_t idx) const
SQLTypeInfo get_agg_type(const SQLAgg agg_kind, const Analyzer::Expr *arg_expr)
bool is_agg_supported_for_type(const SQLAgg &agg_kind, const SQLTypeInfo &arg_ti)
#define CHECK_LT(x, y)
Definition: Logger.h:216
#define CHECK_LE(x, y)
Definition: Logger.h:217
bool takes_arg(const TargetInfo &target_info)
bool isDistinct() const
size_t size() const
bool g_cluster
Definition: sqltypes.h:44
bool is_distinct(const size_t input_idx, const RelAlgNode *node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Analyzer::ExpressionPtr RelAlgTranslator::translateArrayFunction ( const RexFunctionOperator rex_function) const
private

Definition at line 1357 of file RelAlgTranslator.cpp.

References CHECK, get_nullable_logical_type_info(), SQLTypeInfo::get_subtype(), RexOperator::getType(), kARRAY, kBOOLEAN, kENCODING_FIXED, kNULLT, to_string(), TRANSIENT_DICT_ID, and translateFunctionArgs().

Referenced by translateFunction().

1358  {
1359  if (rex_function->getType().get_subtype() == kNULLT) {
1360  auto sql_type = rex_function->getType();
1361  CHECK(sql_type.get_type() == kARRAY);
1362 
1363  // FIX-ME: Deal with NULL arrays
1364  auto translated_function_args(translateFunctionArgs(rex_function));
1365  if (translated_function_args.size() > 0) {
1366  const auto first_element_logical_type =
1367  get_nullable_logical_type_info(translated_function_args[0]->get_type_info());
1368 
1369  auto diff_elem_itr =
1370  std::find_if(translated_function_args.begin(),
1371  translated_function_args.end(),
1372  [first_element_logical_type](const auto expr) {
1373  return first_element_logical_type !=
1374  get_nullable_logical_type_info(expr->get_type_info());
1375  });
1376  if (diff_elem_itr != translated_function_args.end()) {
1377  throw std::runtime_error(
1378  "Element " +
1379  std::to_string(diff_elem_itr - translated_function_args.begin()) +
1380  " is not of the same type as other elements of the array. Consider casting "
1381  "to force this condition.\nElement Type: " +
1382  get_nullable_logical_type_info((*diff_elem_itr)->get_type_info())
1383  .to_string() +
1384  "\nArray type: " + first_element_logical_type.to_string());
1385  }
1386 
1387  if (first_element_logical_type.is_string() &&
1388  !first_element_logical_type.is_dict_encoded_string()) {
1389  sql_type.set_subtype(first_element_logical_type.get_type());
1390  sql_type.set_compression(kENCODING_FIXED);
1391  } else if (first_element_logical_type.is_dict_encoded_string()) {
1392  sql_type.set_subtype(first_element_logical_type.get_type());
1393  sql_type.set_comp_param(TRANSIENT_DICT_ID);
1394  } else {
1395  sql_type.set_subtype(first_element_logical_type.get_type());
1396  sql_type.set_scale(first_element_logical_type.get_scale());
1397  sql_type.set_precision(first_element_logical_type.get_precision());
1398  }
1399 
1400  return makeExpr<Analyzer::ArrayExpr>(sql_type, translated_function_args);
1401  } else {
1402  // defaulting to valid sub-type for convenience
1403  sql_type.set_subtype(kBOOLEAN);
1404  return makeExpr<Analyzer::ArrayExpr>(sql_type, translated_function_args);
1405  }
1406  } else {
1407  return makeExpr<Analyzer::ArrayExpr>(rex_function->getType(),
1408  translateFunctionArgs(rex_function));
1409  }
1410 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:315
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:933
const SQLTypeInfo & getType() const
std::string to_string(char const *&&v)
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
#define TRANSIENT_DICT_ID
Definition: sqltypes.h:253
#define CHECK(condition)
Definition: Logger.h:206

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateBinaryGeoFunction ( const RexFunctionOperator rex_function) const
private

Definition at line 1126 of file RelAlgTranslatorGeo.cpp.

References CHECK_EQ, CHECK_GT, test_fsi::d, Datum::doubleval, fold_expr(), func_resolve, SQLTypeInfo::get_compression(), Geospatial::get_compression_scheme(), SQLTypeInfo::get_input_srid(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_subtype(), SQLTypeInfo::get_type(), RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), Datum::intval, kBOOLEAN, kDOUBLE, kENCODING_GEOINT, kGEOGRAPHY, kINT, kLINESTRING, kNOT, kNULLT, kPOINT, run_benchmark_import::result, RexOperator::size(), anonymous_namespace{GeoIR.cpp}::suffix(), translateGeoColumn(), translateGeoFunctionArg(), and translateScalarRex().

Referenced by translateFunction(), and translateTernaryGeoFunction().

1127  {
1128  auto function_name = rex_function->getName();
1129  auto return_type = rex_function->getType();
1130 
1131  if (function_name == "ST_Overlaps"sv) {
1132  // Overlaps join is the only implementation supported for now, only translate bounds
1133  CHECK_EQ(size_t(2), rex_function->size());
1134  auto extract_geo_bounds_from_input =
1135  [this, &rex_function](const size_t index) -> std::shared_ptr<Analyzer::Expr> {
1136  const auto rex_input =
1137  dynamic_cast<const RexInput*>(rex_function->getOperand(index));
1138  if (rex_input) {
1139  SQLTypeInfo ti;
1140  const auto exprs = translateGeoColumn(rex_input, ti, true, false, false);
1141  CHECK_GT(exprs.size(), size_t(0));
1142  if (ti.get_type() == kPOINT) {
1143  throw std::runtime_error("ST_Overlaps is not supported for point arguments.");
1144  } else {
1145  return exprs.back();
1146  }
1147  } else {
1148  throw std::runtime_error(
1149  "Only inputs are supported as arguments to ST_Overlaps for now.");
1150  }
1151  };
1152  std::vector<std::shared_ptr<Analyzer::Expr>> geo_args;
1153  geo_args.push_back(extract_geo_bounds_from_input(0));
1154  geo_args.push_back(extract_geo_bounds_from_input(1));
1155 
1156  return makeExpr<Analyzer::FunctionOper>(return_type, function_name, geo_args);
1157  }
1158 
1159  bool swap_args = false;
1160  bool with_bounds = false;
1161  bool negate_result = false;
1162  Analyzer::ExpressionPtr threshold_expr = nullptr;
1163  if (function_name == "ST_DWithin"sv) {
1164  CHECK_EQ(size_t(3), rex_function->size());
1165  function_name = "ST_Distance";
1166  return_type = SQLTypeInfo(kDOUBLE, false);
1167  // Inject ST_DWithin's short-circuiting threshold into ST_MaxDistance
1168  threshold_expr = translateScalarRex(rex_function->getOperand(2));
1169  } else if (function_name == "ST_DFullyWithin"sv) {
1170  CHECK_EQ(size_t(3), rex_function->size());
1171  function_name = "ST_MaxDistance";
1172  return_type = SQLTypeInfo(kDOUBLE, false);
1173  // TODO: inject ST_DFullyWithin's short-circuiting threshold into ST_MaxDistance
1174  threshold_expr = nullptr;
1175  } else if (function_name == "ST_Distance"sv) {
1176  // TODO: pick up an outside short-circuiting threshold and inject into ST_Distance
1177  threshold_expr = nullptr;
1178  } else if (function_name == "ST_MaxDistance"sv) {
1179  // TODO: pick up an outside short-circuiting threshold and inject into
1180  // ST_MaxDistance
1181  threshold_expr = nullptr;
1182  } else {
1183  CHECK_EQ(size_t(2), rex_function->size());
1184  }
1185  if (function_name == "ST_Within"sv) {
1186  function_name = "ST_Contains";
1187  swap_args = true;
1188  } else if (function_name == "ST_Disjoint"sv) {
1189  function_name = "ST_Intersects";
1190  negate_result = true;
1191  }
1192  if (func_resolve(
1193  function_name, "ST_Contains"sv, "ST_Intersects"sv, "ST_Approx_Overlaps"sv)) {
1194  with_bounds = true;
1195  }
1196 
1197  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
1198  SQLTypeInfo arg0_ti;
1199  SQLTypeInfo arg1_ti;
1200  int32_t lindex0 = 0;
1201  int32_t lindex1 = 0;
1202 
1203  auto geoargs0 = translateGeoFunctionArg(rex_function->getOperand(swap_args ? 1 : 0),
1204  arg0_ti,
1205  lindex0,
1206  with_bounds,
1207  false,
1208  false);
1209  if (arg0_ti.get_type() == kLINESTRING) {
1210  Datum index;
1211  index.intval = lindex0;
1212  geoargs0.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
1213  }
1214  geoargs.insert(geoargs.end(), geoargs0.begin(), geoargs0.end());
1215 
1216  // If first arg of ST_Contains is compressed, try to compress the second one
1217  // to be able to switch to ST_cContains
1218  bool try_to_compress_arg1 = (function_name == "ST_Contains"sv &&
1219  arg0_ti.get_compression() == kENCODING_GEOINT &&
1220  arg0_ti.get_output_srid() == 4326);
1221 
1222  auto geoargs1 = translateGeoFunctionArg(rex_function->getOperand(swap_args ? 0 : 1),
1223  arg1_ti,
1224  lindex1,
1225  with_bounds,
1226  false,
1227  false,
1228  false,
1229  false,
1230  try_to_compress_arg1);
1231  if (arg1_ti.get_type() == kLINESTRING) {
1232  Datum index;
1233  index.intval = lindex1;
1234  geoargs1.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
1235  }
1236  geoargs.insert(geoargs.end(), geoargs1.begin(), geoargs1.end());
1237 
1238  if (arg0_ti.get_subtype() != kNULLT && arg0_ti.get_subtype() != arg1_ti.get_subtype()) {
1239  throw QueryNotSupported(rex_function->getName() +
1240  " accepts either two GEOGRAPHY or two GEOMETRY arguments");
1241  }
1242  // Check SRID match if at least one is set/valid
1243  if ((arg0_ti.get_output_srid() > 0 || arg1_ti.get_output_srid() > 0) &&
1244  arg0_ti.get_output_srid() != arg1_ti.get_output_srid()) {
1245  throw QueryNotSupported(rex_function->getName() + " cannot accept different SRIDs");
1246  }
1247 
1248  if (function_name == "ST_Contains"sv) {
1249  const bool lhs_is_literal =
1250  geoargs1.size() == 1 &&
1251  std::dynamic_pointer_cast<const Analyzer::Constant>(geoargs1.front()) != nullptr;
1252  const bool lhs_is_point = arg1_ti.get_type() == kPOINT;
1253  if (!lhs_is_literal && lhs_is_point &&
1254  arg0_ti.get_compression() == kENCODING_GEOINT &&
1255  arg0_ti.get_input_srid() == arg0_ti.get_output_srid() &&
1256  arg0_ti.get_compression() == arg1_ti.get_compression() &&
1257  arg1_ti.get_input_srid() == arg1_ti.get_output_srid()) {
1258  // use the compressed version of ST_Contains
1259  function_name = "ST_cContains";
1260  }
1261  }
1262 
1263  std::string specialized_geofunc{function_name + suffix(arg0_ti.get_type()) +
1264  suffix(arg1_ti.get_type())};
1265 
1266  if (arg0_ti.get_subtype() == kGEOGRAPHY && arg0_ti.get_output_srid() == 4326) {
1267  // Need to call geodesic runtime functions
1268  if (function_name == "ST_Distance"sv) {
1269  if ((arg0_ti.get_type() == kPOINT ||
1270  (arg0_ti.get_type() == kLINESTRING && lindex0 != 0)) &&
1271  (arg1_ti.get_type() == kPOINT ||
1272  (arg1_ti.get_type() == kLINESTRING && lindex1 != 0))) {
1273  // Geodesic distance between points (or indexed linestrings)
1274  specialized_geofunc += "_Geodesic"s;
1275  } else {
1276  throw QueryNotSupported(function_name +
1277  " currently doesn't accept non-POINT geographies");
1278  }
1279  } else if (rex_function->getName() == "ST_Contains"sv) {
1280  // We currently don't have a geodesic implementation of ST_Contains,
1281  // allowing calls to a [less precise] cartesian implementation.
1282  } else {
1283  throw QueryNotSupported(function_name + " doesn't accept geographies");
1284  }
1285  } else if (function_name == "ST_Distance"sv && rex_function->size() == 3) {
1286  if (arg0_ti.get_type() == kPOINT && arg1_ti.get_type() == kPOINT) {
1287  // Cartesian distance between points used by ST_DWithin - switch to faster Squared
1288  specialized_geofunc += "_Squared"s;
1289  }
1290  }
1291 
1292  // Add first input's compression mode and SRID args to enable on-the-fly
1293  // decompression/transforms
1294  Datum input_compression0;
1295  input_compression0.intval = Geospatial::get_compression_scheme(arg0_ti);
1296  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression0));
1297  Datum input_srid0;
1298  input_srid0.intval = arg0_ti.get_input_srid();
1299  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid0));
1300 
1301  // Add second input's compression mode and SRID args to enable on-the-fly
1302  // decompression/transforms
1303  Datum input_compression1;
1304  input_compression1.intval = Geospatial::get_compression_scheme(arg1_ti);
1305  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression1));
1306  Datum input_srid1;
1307  input_srid1.intval = arg1_ti.get_input_srid();
1308  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid1));
1309 
1310  // Add output SRID arg to enable on-the-fly transforms
1311  Datum output_srid;
1312  output_srid.intval = arg0_ti.get_output_srid();
1313  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
1314 
1315  // Some geo distance functions will be injected with a short-circuit threshold.
1316  // Threshold value would come from Geo comparison operations or from other outer
1317  // geo operations, e.g. ST_DWithin
1318  // At this point, only ST_Distance_LineString_LineString requires a threshold arg.
1319  // TODO: Other combinations that involve LINESTRING, POLYGON and MULTIPOLYGON args
1320  // TODO: Inject threshold into ST_MaxDistance
1321  if (function_name == "ST_Distance"sv && arg0_ti.get_subtype() != kGEOGRAPHY &&
1322  (arg0_ti.get_type() != kPOINT || arg1_ti.get_type() != kPOINT)) {
1323  if (threshold_expr) {
1324  if (threshold_expr->get_type_info().get_type() != kDOUBLE) {
1325  const auto& threshold_ti = SQLTypeInfo(kDOUBLE, false);
1326  threshold_expr = threshold_expr->add_cast(threshold_ti);
1327  }
1328  threshold_expr = fold_expr(threshold_expr.get());
1329  } else {
1330  Datum d;
1331  d.doubleval = 0.0;
1332  threshold_expr = makeExpr<Analyzer::Constant>(kDOUBLE, false, d);
1333  }
1334  geoargs.push_back(threshold_expr);
1335  }
1336 
1337  auto result =
1338  makeExpr<Analyzer::FunctionOper>(return_type, specialized_geofunc, geoargs);
1339  if (negate_result) {
1340  return makeExpr<Analyzer::UOper>(kBOOLEAN, kNOT, result);
1341  }
1342  return result;
1343 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:315
#define CHECK_EQ(x, y)
Definition: Logger.h:214
auto func_resolve
tuple d
Definition: test_fsi.py:9
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
std::shared_ptr< Analyzer::Expr > ExpressionPtr
Definition: Analyzer.h:180
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
#define CHECK_GT(x, y)
Definition: Logger.h:218
int32_t intval
Definition: sqltypes.h:208
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:322
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:318
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
Definition: sqltypes.h:44
const std::string & getName() const
std::string suffix(SQLTypes type)
Definition: GeoIR.cpp:156
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoColumn(const RexInput *, SQLTypeInfo &, const bool with_bounds, const bool with_render_group, const bool expand_geo_col) const
Definition: sqldefs.h:39
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
double doubleval
Definition: sqltypes.h:211
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:320

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Analyzer::ExpressionPtr RelAlgTranslator::translateCardinality ( const RexFunctionOperator rex_function) const
private

Definition at line 1245 of file RelAlgTranslator.cpp.

References RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), kARRAY, anonymous_namespace{RelAlgTranslator.cpp}::makeNumericConstant(), and translateScalarRex().

Referenced by translateFunction().

1246  {
1247  const auto ret_ti = rex_function->getType();
1248  const auto arg = translateScalarRex(rex_function->getOperand(0));
1249  const auto arg_ti = arg->get_type_info();
1250  if (!arg_ti.is_array()) {
1251  throw std::runtime_error(rex_function->getName() + " expects an array expression.");
1252  }
1253  if (arg_ti.get_subtype() == kARRAY) {
1254  throw std::runtime_error(rex_function->getName() +
1255  " expects one-dimension array expression.");
1256  }
1257  const auto array_size = arg_ti.get_size();
1258  const auto array_elem_size = arg_ti.get_elem_type().get_array_context_logical_size();
1259 
1260  if (array_size > 0) {
1261  if (array_elem_size <= 0) {
1262  throw std::runtime_error(rex_function->getName() +
1263  ": unexpected array element type.");
1264  }
1265  // Return cardinality of a fixed length array
1266  return makeNumericConstant(ret_ti, array_size / array_elem_size);
1267  }
1268  // Variable length array cardinality will be calculated at runtime
1269  return makeExpr<Analyzer::CardinalityExpr>(arg);
1270 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< Analyzer::Constant > makeNumericConstant(const SQLTypeInfo &ti, const long val)
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateCase ( const RexCase rex_case) const
private

Definition at line 921 of file RelAlgTranslator.cpp.

References RexCase::branchCount(), RexCase::getElse(), RexCase::getThen(), RexCase::getWhen(), i, Parser::CaseExpr::normalize(), and translateScalarRex().

Referenced by translateScalarRex().

922  {
923  std::shared_ptr<Analyzer::Expr> else_expr;
924  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
925  expr_list;
926  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
927  const auto when_expr = translateScalarRex(rex_case->getWhen(i));
928  const auto then_expr = translateScalarRex(rex_case->getThen(i));
929  expr_list.emplace_back(when_expr, then_expr);
930  }
931  if (rex_case->getElse()) {
932  else_expr = translateScalarRex(rex_case->getElse());
933  }
934  return Parser::CaseExpr::normalize(expr_list, else_expr);
935 }
const RexScalar * getThen(const size_t idx) const
const RexScalar * getElse() const
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const RexScalar * getWhen(const size_t idx) const
static std::shared_ptr< Analyzer::Expr > normalize(const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr >>> &, const std::shared_ptr< Analyzer::Expr >)
Definition: ParserNode.cpp:934
size_t branchCount() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateCurrentDate ( ) const
private

Definition at line 1281 of file RelAlgTranslator.cpp.

References Datum::bigintval, is_null(), kDATE, and now_.

Referenced by translateFunction().

1281  {
1282  constexpr bool is_null = false;
1283  Datum datum;
1284  datum.bigintval = now_ - now_ % (24 * 60 * 60); // Assumes 0 < now_.
1285  return makeExpr<Analyzer::Constant>(kDATE, is_null, datum);
1286 }
CONSTEXPR DEVICE bool is_null(const T &value)
int64_t bigintval
Definition: sqltypes.h:209
Definition: sqltypes.h:52

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateCurrentTime ( ) const
private

Definition at line 1288 of file RelAlgTranslator.cpp.

References Datum::bigintval, is_null(), kTIME, and now_.

Referenced by translateFunction().

1288  {
1289  constexpr bool is_null = false;
1290  Datum datum;
1291  datum.bigintval = now_ % (24 * 60 * 60); // Assumes 0 < now_.
1292  return makeExpr<Analyzer::Constant>(kTIME, is_null, datum);
1293 }
Definition: sqltypes.h:48
CONSTEXPR DEVICE bool is_null(const T &value)
int64_t bigintval
Definition: sqltypes.h:209

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateCurrentTimestamp ( ) const
private

Definition at line 1295 of file RelAlgTranslator.cpp.

References Parser::TimestampLiteral::get(), and now_.

Referenced by translateDatetime(), and translateFunction().

1295  {
1297 }
static std::shared_ptr< Analyzer::Expr > get(const int64_t)
Definition: ParserNode.cpp:194

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateCurrentUser ( const RexFunctionOperator rex_function) const
private

Definition at line 1221 of file RelAlgTranslator.cpp.

References Parser::UserLiteral::get(), and query_state_.

Referenced by translateFunction().

1222  {
1223  std::string user{"SESSIONLESS_USER"};
1224  if (query_state_) {
1225  user = query_state_->getConstSessionInfo()->get_currentUser().userName;
1226  }
1227  return Parser::UserLiteral::get(user);
1228 }
static std::shared_ptr< Analyzer::Expr > get(const std::string &)
Definition: ParserNode.cpp:208
std::shared_ptr< const query_state::QueryState > query_state_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateDateadd ( const RexFunctionOperator rex_function) const
private

Definition at line 1050 of file RelAlgTranslator.cpp.

References CHECK_EQ, field(), RexOperator::getOperand(), kBIGINT, kTIME, kTIMESTAMP, RexOperator::size(), to_dateadd_field(), translateScalarRex(), and anonymous_namespace{RelAlgTranslator.cpp}::validate_datetime_datepart_argument().

Referenced by translateFunction().

1051  {
1052  CHECK_EQ(size_t(3), rex_function->size());
1053  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
1054  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
1056  const auto number_units = translateScalarRex(rex_function->getOperand(1));
1057  const auto number_units_const =
1058  std::dynamic_pointer_cast<Analyzer::Constant>(number_units);
1059  if (number_units_const && number_units_const->get_is_null()) {
1060  throw std::runtime_error("The 'Interval' argument literal must not be 'null'.");
1061  }
1062  const auto cast_number_units = number_units->add_cast(SQLTypeInfo(kBIGINT, false));
1063  const auto datetime = translateScalarRex(rex_function->getOperand(2));
1064  const auto& datetime_ti = datetime->get_type_info();
1065  if (datetime_ti.get_type() == kTIME) {
1066  throw std::runtime_error("DateAdd operation not supported for TIME.");
1067  }
1068  const auto& field = to_dateadd_field(*timeunit_lit->get_constval().stringval);
1069  const int dim = datetime_ti.get_dimension();
1070  return makeExpr<Analyzer::DateaddExpr>(
1071  SQLTypeInfo(kTIMESTAMP, dim, 0, false), field, cast_number_units, datetime);
1072 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
Definition: sqltypes.h:48
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
void validate_datetime_datepart_argument(const std::shared_ptr< Analyzer::Constant > literal_expr)
DateaddField to_dateadd_field(const std::string &field)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateDatediff ( const RexFunctionOperator rex_function) const
private

Definition at line 1165 of file RelAlgTranslator.cpp.

References CHECK_EQ, field(), RexOperator::getOperand(), kBIGINT, RexOperator::size(), to_datediff_field(), translateScalarRex(), and anonymous_namespace{RelAlgTranslator.cpp}::validate_datetime_datepart_argument().

Referenced by translateFunction().

1166  {
1167  CHECK_EQ(size_t(3), rex_function->size());
1168  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
1169  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
1171  const auto start = translateScalarRex(rex_function->getOperand(1));
1172  const auto end = translateScalarRex(rex_function->getOperand(2));
1173  const auto field = to_datediff_field(*timeunit_lit->get_constval().stringval);
1174  return makeExpr<Analyzer::DatediffExpr>(SQLTypeInfo(kBIGINT, false), field, start, end);
1175 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
DatetruncField to_datediff_field(const std::string &field)
void validate_datetime_datepart_argument(const std::shared_ptr< Analyzer::Constant > literal_expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateDatepart ( const RexFunctionOperator rex_function) const
private

Definition at line 1177 of file RelAlgTranslator.cpp.

References CHECK_EQ, ExtractExpr::generate(), RexOperator::getOperand(), RexOperator::size(), to_datepart_field(), translateScalarRex(), and anonymous_namespace{RelAlgTranslator.cpp}::validate_datetime_datepart_argument().

Referenced by translateFunction().

1178  {
1179  CHECK_EQ(size_t(2), rex_function->size());
1180  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
1181  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
1183  const auto from_expr = translateScalarRex(rex_function->getOperand(1));
1184  return ExtractExpr::generate(
1185  from_expr, to_datepart_field(*timeunit_lit->get_constval().stringval));
1186 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
ExtractField to_datepart_field(const std::string &field)
const std::shared_ptr< Analyzer::Expr > generate() const
void validate_datetime_datepart_argument(const std::shared_ptr< Analyzer::Constant > literal_expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateDatePlusMinus ( const RexOperator rex_operator) const
private

Definition at line 1083 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, CHECK, daMONTH, daSECOND, dtMONTH, dtSECOND, fold_expr(), anonymous_namespace{RelAlgTranslator.cpp}::get_datetimeplus_rewrite_funcname(), RexOperator::getOperand(), RexOperator::getOperator(), RexOperator::getType(), kBIGINT, kDATE, kDIVIDE, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kMINUS, kMULTIPLY, kONE, kPLUS, kTIME, kTIMESTAMP, kUMINUS, anonymous_namespace{RelAlgTranslator.cpp}::makeNumericConstant(), run_benchmark_import::result, rewrite_to_date_trunc(), RexOperator::size(), and translateScalarRex().

Referenced by translateOper().

1084  {
1085  if (rex_operator->size() != 2) {
1086  return nullptr;
1087  }
1088  const auto datetime = translateScalarRex(rex_operator->getOperand(0));
1089  const auto datetime_ti = datetime->get_type_info();
1090  if (!datetime_ti.is_timestamp() && !datetime_ti.is_date()) {
1091  if (datetime_ti.get_type() == kTIME) {
1092  throw std::runtime_error("DateTime addition/subtraction not supported for TIME.");
1093  }
1094  return nullptr;
1095  }
1096  const auto rhs = translateScalarRex(rex_operator->getOperand(1));
1097  const auto rhs_ti = rhs->get_type_info();
1098  if (rhs_ti.get_type() == kTIMESTAMP || rhs_ti.get_type() == kDATE) {
1099  if (datetime_ti.is_high_precision_timestamp() ||
1100  rhs_ti.is_high_precision_timestamp()) {
1101  throw std::runtime_error(
1102  "High Precision timestamps are not supported for TIMESTAMPDIFF operation. "
1103  "Use "
1104  "DATEDIFF.");
1105  }
1106  auto bigint_ti = SQLTypeInfo(kBIGINT, false);
1107  const auto& rex_operator_ti = rex_operator->getType();
1108  const auto datediff_field =
1109  (rex_operator_ti.get_type() == kINTERVAL_DAY_TIME) ? dtSECOND : dtMONTH;
1110  auto result =
1111  makeExpr<Analyzer::DatediffExpr>(bigint_ti, datediff_field, rhs, datetime);
1112  // multiply 1000 to result since expected result should be in millisecond precision.
1113  if (rex_operator_ti.get_type() == kINTERVAL_DAY_TIME) {
1114  return makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1115  kMULTIPLY,
1116  kONE,
1117  result,
1118  makeNumericConstant(bigint_ti, 1000));
1119  } else {
1120  return result;
1121  }
1122  }
1123  const auto op = rex_operator->getOperator();
1124  if (op == kPLUS) {
1125  std::vector<std::shared_ptr<Analyzer::Expr>> args = {datetime, rhs};
1126  auto dt_plus = makeExpr<Analyzer::FunctionOper>(
1127  datetime_ti, get_datetimeplus_rewrite_funcname(op), args);
1128  const auto date_trunc = rewrite_to_date_trunc(dt_plus.get());
1129  if (date_trunc) {
1130  return date_trunc;
1131  }
1132  }
1133  const auto interval = fold_expr(rhs.get());
1134  auto interval_ti = interval->get_type_info();
1135  auto bigint_ti = SQLTypeInfo(kBIGINT, false);
1136  const auto interval_lit = std::dynamic_pointer_cast<Analyzer::Constant>(interval);
1137  if (interval_ti.get_type() == kINTERVAL_DAY_TIME) {
1138  std::shared_ptr<Analyzer::Expr> interval_sec;
1139  if (interval_lit) {
1140  interval_sec =
1141  makeNumericConstant(bigint_ti,
1142  (op == kMINUS ? -interval_lit->get_constval().bigintval
1143  : interval_lit->get_constval().bigintval) /
1144  1000);
1145  } else {
1146  interval_sec = makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1147  kDIVIDE,
1148  kONE,
1149  interval,
1150  makeNumericConstant(bigint_ti, 1000));
1151  if (op == kMINUS) {
1152  interval_sec =
1153  std::make_shared<Analyzer::UOper>(bigint_ti, false, kUMINUS, interval_sec);
1154  }
1155  }
1156  return makeExpr<Analyzer::DateaddExpr>(datetime_ti, daSECOND, interval_sec, datetime);
1157  }
1158  CHECK(interval_ti.get_type() == kINTERVAL_YEAR_MONTH);
1159  const auto interval_months = op == kMINUS ? std::make_shared<Analyzer::UOper>(
1160  bigint_ti, false, kUMINUS, interval)
1161  : interval;
1162  return makeExpr<Analyzer::DateaddExpr>(datetime_ti, daMONTH, interval_months, datetime);
1163 }
Definition: sqltypes.h:48
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
Definition: sqldefs.h:41
std::shared_ptr< Analyzer::Constant > makeNumericConstant(const SQLTypeInfo &ti, const long val)
SQLOps getOperator() const
Definition: sqltypes.h:52
Definition: sqldefs.h:40
Definition: sqldefs.h:69
#define CHECK(condition)
Definition: Logger.h:206
std::string get_datetimeplus_rewrite_funcname(const SQLOps &op)
std::shared_ptr< Analyzer::Expr > rewrite_to_date_trunc(const Analyzer::FunctionOper *dt_plus)
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateDatetime ( const RexFunctionOperator rex_function) const
private

Definition at line 1299 of file RelAlgTranslator.cpp.

References CHECK, CHECK_EQ, RexOperator::getOperand(), RexOperator::size(), translateCurrentTimestamp(), and translateScalarRex().

Referenced by translateFunction().

1300  {
1301  CHECK_EQ(size_t(1), rex_function->size());
1302  const auto arg = translateScalarRex(rex_function->getOperand(0));
1303  const auto arg_lit = std::dynamic_pointer_cast<Analyzer::Constant>(arg);
1304  const std::string datetime_err{R"(Only DATETIME('NOW') supported for now.)"};
1305  if (!arg_lit || arg_lit->get_is_null()) {
1306  throw std::runtime_error(datetime_err);
1307  }
1308  CHECK(arg_lit->get_type_info().is_string());
1309  if (*arg_lit->get_constval().stringval != "NOW"sv) {
1310  throw std::runtime_error(datetime_err);
1311  }
1312  return translateCurrentTimestamp();
1313 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateCurrentTimestamp() const
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
#define CHECK(condition)
Definition: Logger.h:206

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateExtract ( const RexFunctionOperator rex_function) const
private

Definition at line 991 of file RelAlgTranslator.cpp.

References CHECK_EQ, ExtractExpr::generate(), DateTruncExpr::generate(), RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::size(), translateScalarRex(), and anonymous_namespace{RelAlgTranslator.cpp}::validate_datetime_datepart_argument().

Referenced by translateFunction().

992  {
993  CHECK_EQ(size_t(2), rex_function->size());
994  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
995  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
997  const auto from_expr = translateScalarRex(rex_function->getOperand(1));
998  const bool is_date_trunc = rex_function->getName() == "PG_DATE_TRUNC"sv;
999  if (is_date_trunc) {
1000  return DateTruncExpr::generate(from_expr, *timeunit_lit->get_constval().stringval);
1001  } else {
1002  return ExtractExpr::generate(from_expr, *timeunit_lit->get_constval().stringval);
1003  }
1004 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
const std::shared_ptr< Analyzer::Expr > generate() const
const std::string & getName() const
void validate_datetime_datepart_argument(const std::shared_ptr< Analyzer::Constant > literal_expr)
const std::shared_ptr< Analyzer::Expr > generate() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateFunction ( const RexFunctionOperator rex_function) const
private

Definition at line 1412 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, bind_function(), CHECK, CHECK_EQ, test_fsi::d, ext_arg_type_to_type_info(), func_resolve, g_enable_experimental_string_functions, RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), i, SQLTypeInfo::is_decimal(), kDIVIDE, kONE, kSMALLINT, kTEXT, LOG, Parser::OperExpr::normalize(), rewrite_to_date_trunc(), SQLTypeInfo::set_notnull(), RexOperator::size(), Datum::smallintval, t, translateAbs(), translateArrayFunction(), translateBinaryGeoFunction(), translateCardinality(), translateCurrentDate(), translateCurrentTime(), translateCurrentTimestamp(), translateCurrentUser(), translateDateadd(), translateDatediff(), translateDatepart(), translateDatetime(), translateExtract(), translateFunctionArgs(), translateFunctionWithGeoArg(), translateGeoBinaryConstructor(), translateGeoPredicate(), translateGeoProjection(), translateHPTLiteral(), translateItem(), translateKeyForString(), translateLength(), translateLike(), translateLikely(), translateLower(), translateOffsetInFragment(), translateRegexp(), translateSampleRatio(), translateScalarRex(), translateSign(), translateTernaryGeoFunction(), translateUnaryGeoFunction(), translateUnlikely(), and logger::WARNING.

Referenced by translateScalarRex().

1413  {
1414  if (func_resolve(rex_function->getName(), "LIKE"sv, "PG_ILIKE"sv)) {
1415  return translateLike(rex_function);
1416  }
1417  if (rex_function->getName() == "REGEXP_LIKE"sv) {
1418  return translateRegexp(rex_function);
1419  }
1420  if (rex_function->getName() == "LIKELY"sv) {
1421  return translateLikely(rex_function);
1422  }
1423  if (rex_function->getName() == "UNLIKELY"sv) {
1424  return translateUnlikely(rex_function);
1425  }
1426  if (func_resolve(rex_function->getName(), "PG_EXTRACT"sv, "PG_DATE_TRUNC"sv)) {
1427  return translateExtract(rex_function);
1428  }
1429  if (rex_function->getName() == "DATEADD"sv) {
1430  return translateDateadd(rex_function);
1431  }
1432  if (rex_function->getName() == "DATEDIFF"sv) {
1433  return translateDatediff(rex_function);
1434  }
1435  if (rex_function->getName() == "DATEPART"sv) {
1436  return translateDatepart(rex_function);
1437  }
1438  if (func_resolve(rex_function->getName(), "LENGTH"sv, "CHAR_LENGTH"sv)) {
1439  return translateLength(rex_function);
1440  }
1441  if (rex_function->getName() == "KEY_FOR_STRING"sv) {
1442  return translateKeyForString(rex_function);
1443  }
1444  if (rex_function->getName() == "SAMPLE_RATIO"sv) {
1445  return translateSampleRatio(rex_function);
1446  }
1447  if (rex_function->getName() == "CURRENT_USER"sv) {
1448  return translateCurrentUser(rex_function);
1449  }
1450  if (g_enable_experimental_string_functions && rex_function->getName() == "LOWER"sv) {
1451  return translateLower(rex_function);
1452  }
1453  if (func_resolve(rex_function->getName(), "CARDINALITY"sv, "ARRAY_LENGTH"sv)) {
1454  return translateCardinality(rex_function);
1455  }
1456  if (rex_function->getName() == "ITEM"sv) {
1457  return translateItem(rex_function);
1458  }
1459  if (rex_function->getName() == "CURRENT_DATE"sv) {
1460  return translateCurrentDate();
1461  }
1462  if (rex_function->getName() == "CURRENT_TIME"sv) {
1463  return translateCurrentTime();
1464  }
1465  if (rex_function->getName() == "CURRENT_TIMESTAMP"sv) {
1466  return translateCurrentTimestamp();
1467  }
1468  if (rex_function->getName() == "NOW"sv) {
1469  return translateCurrentTimestamp();
1470  }
1471  if (rex_function->getName() == "DATETIME"sv) {
1472  return translateDatetime(rex_function);
1473  }
1474  if (func_resolve(rex_function->getName(), "usTIMESTAMP"sv, "nsTIMESTAMP"sv)) {
1475  return translateHPTLiteral(rex_function);
1476  }
1477  if (rex_function->getName() == "ABS"sv) {
1478  return translateAbs(rex_function);
1479  }
1480  if (rex_function->getName() == "SIGN"sv) {
1481  return translateSign(rex_function);
1482  }
1483  if (func_resolve(rex_function->getName(), "CEIL"sv, "FLOOR"sv)) {
1484  return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1485  rex_function->getType(),
1486  rex_function->getName(),
1487  translateFunctionArgs(rex_function));
1488  } else if (rex_function->getName() == "ROUND"sv) {
1489  std::vector<std::shared_ptr<Analyzer::Expr>> args =
1490  translateFunctionArgs(rex_function);
1491 
1492  if (rex_function->size() == 1) {
1493  // push a 0 constant if 2nd operand is missing.
1494  // this needs to be done as calcite returns
1495  // only the 1st operand without defaulting the 2nd one
1496  // when the user did not specify the 2nd operand.
1497  SQLTypes t = kSMALLINT;
1498  Datum d;
1499  d.smallintval = 0;
1500  args.push_back(makeExpr<Analyzer::Constant>(t, false, d));
1501  }
1502 
1503  // make sure we have only 2 operands
1504  CHECK(args.size() == 2);
1505 
1506  if (!args[0]->get_type_info().is_number()) {
1507  throw std::runtime_error("Only numeric 1st operands are supported");
1508  }
1509 
1510  // the 2nd operand does not need to be a constant
1511  // it can happily reference another integer column
1512  if (!args[1]->get_type_info().is_integer()) {
1513  throw std::runtime_error("Only integer 2nd operands are supported");
1514  }
1515 
1516  // Calcite may upcast decimals in a way that is
1517  // incompatible with the extension function input. Play it safe and stick with the
1518  // argument type instead.
1519  const SQLTypeInfo ret_ti = args[0]->get_type_info().is_decimal()
1520  ? args[0]->get_type_info()
1521  : rex_function->getType();
1522 
1523  return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1524  ret_ti, rex_function->getName(), args);
1525  }
1526  if (rex_function->getName() == "DATETIME_PLUS"sv) {
1527  auto dt_plus = makeExpr<Analyzer::FunctionOper>(rex_function->getType(),
1528  rex_function->getName(),
1529  translateFunctionArgs(rex_function));
1530  const auto date_trunc = rewrite_to_date_trunc(dt_plus.get());
1531  if (date_trunc) {
1532  return date_trunc;
1533  }
1534  return translateDateadd(rex_function);
1535  }
1536  if (rex_function->getName() == "/INT"sv) {
1537  CHECK_EQ(size_t(2), rex_function->size());
1538  std::shared_ptr<Analyzer::Expr> lhs = translateScalarRex(rex_function->getOperand(0));
1539  std::shared_ptr<Analyzer::Expr> rhs = translateScalarRex(rex_function->getOperand(1));
1540  const auto rhs_lit = std::dynamic_pointer_cast<Analyzer::Constant>(rhs);
1541  return Parser::OperExpr::normalize(kDIVIDE, kONE, lhs, rhs);
1542  }
1543  if (rex_function->getName() == "Reinterpret"sv) {
1544  CHECK_EQ(size_t(1), rex_function->size());
1545  return translateScalarRex(rex_function->getOperand(0));
1546  }
1547  if (func_resolve(rex_function->getName(),
1548  "ST_X"sv,
1549  "ST_Y"sv,
1550  "ST_XMin"sv,
1551  "ST_YMin"sv,
1552  "ST_XMax"sv,
1553  "ST_YMax"sv,
1554  "ST_NRings"sv,
1555  "ST_NPoints"sv,
1556  "ST_Length"sv,
1557  "ST_Perimeter"sv,
1558  "ST_Area"sv,
1559  "ST_SRID"sv,
1560  "MapD_GeoPolyBoundsPtr"sv /* deprecated */,
1561  "MapD_GeoPolyBoundsPtr"sv /* deprecated */,
1562  "OmniSci_Geo_PolyBoundsPtr"sv,
1563  "OmniSci_Geo_PolyRenderGroup"sv)) {
1564  CHECK_EQ(rex_function->size(), size_t(1));
1565  return translateUnaryGeoFunction(rex_function);
1566  }
1567  if (func_resolve(rex_function->getName(),
1568  "convert_meters_to_pixel_width"sv,
1569  "convert_meters_to_pixel_height"sv,
1570  "is_point_in_view"sv,
1571  "is_point_size_in_view"sv)) {
1572  return translateFunctionWithGeoArg(rex_function);
1573  }
1574  if (func_resolve(rex_function->getName(),
1575  "ST_Distance"sv,
1576  "ST_MaxDistance"sv,
1577  "ST_Intersects"sv,
1578  "ST_Disjoint"sv,
1579  "ST_Contains"sv,
1580  "ST_Overlaps"sv,
1581  "ST_Approx_Overlaps"sv,
1582  "ST_Within"sv)) {
1583  CHECK_EQ(rex_function->size(), size_t(2));
1584  return translateBinaryGeoFunction(rex_function);
1585  }
1586  if (func_resolve(rex_function->getName(), "ST_DWithin"sv, "ST_DFullyWithin"sv)) {
1587  CHECK_EQ(rex_function->size(), size_t(3));
1588  return translateTernaryGeoFunction(rex_function);
1589  }
1590  if (rex_function->getName() == "OFFSET_IN_FRAGMENT"sv) {
1591  CHECK_EQ(size_t(0), rex_function->size());
1592  return translateOffsetInFragment();
1593  }
1594  if (rex_function->getName() == "ARRAY"sv) {
1595  // Var args; currently no check. Possible fix-me -- can array have 0 elements?
1596  return translateArrayFunction(rex_function);
1597  }
1598  if (func_resolve(rex_function->getName(),
1599  "ST_GeomFromText"sv,
1600  "ST_GeogFromText"sv,
1601  "ST_Point"sv,
1602  "ST_Centroid"sv,
1603  "ST_SetSRID"sv)) {
1604  SQLTypeInfo ti;
1605  return translateGeoProjection(rex_function, ti, false);
1606  }
1607  if (func_resolve(rex_function->getName(),
1608  "ST_Intersection"sv,
1609  "ST_Difference"sv,
1610  "ST_Union"sv,
1611  "ST_Buffer"sv)) {
1612  SQLTypeInfo ti;
1613  return translateGeoBinaryConstructor(rex_function, ti, false);
1614  }
1615  if (func_resolve(rex_function->getName(), "ST_IsEmpty"sv, "ST_IsValid"sv)) {
1616  SQLTypeInfo ti;
1617  return translateGeoPredicate(rex_function, ti, false);
1618  }
1619 
1620  auto arg_expr_list = translateFunctionArgs(rex_function);
1621  if (rex_function->getName() == std::string("||") ||
1622  rex_function->getName() == std::string("SUBSTRING")) {
1623  SQLTypeInfo ret_ti(kTEXT, false);
1624  return makeExpr<Analyzer::FunctionOper>(
1625  ret_ti, rex_function->getName(), arg_expr_list);
1626  }
1627  // Reset possibly wrong return type of rex_function to the return
1628  // type of the optimal valid implementation. The return type can be
1629  // wrong in the case of multiple implementations of UDF functions
1630  // that have different return types but Calcite specifies the return
1631  // type according to the first implementation.
1632  SQLTypeInfo ret_ti;
1633  try {
1634  auto ext_func_sig = bind_function(rex_function->getName(), arg_expr_list);
1635 
1636  auto ext_func_args = ext_func_sig.getArgs();
1637  CHECK_EQ(arg_expr_list.size(), ext_func_args.size());
1638  for (size_t i = 0; i < arg_expr_list.size(); i++) {
1639  // fold casts on constants
1640  if (auto constant =
1641  std::dynamic_pointer_cast<Analyzer::Constant>(arg_expr_list[i])) {
1642  auto ext_func_arg_ti = ext_arg_type_to_type_info(ext_func_args[i]);
1643  if (ext_func_arg_ti != arg_expr_list[i]->get_type_info()) {
1644  arg_expr_list[i] = constant->add_cast(ext_func_arg_ti);
1645  }
1646  }
1647  }
1648 
1649  ret_ti = ext_arg_type_to_type_info(ext_func_sig.getRet());
1650  } catch (ExtensionFunctionBindingError& e) {
1651  LOG(WARNING) << "RelAlgTranslator::translateFunction: " << e.what();
1652  throw;
1653  }
1654 
1655  // By default, the extension function type will not allow nulls. If one of the arguments
1656  // is nullable, the extension function must also explicitly allow nulls.
1657  bool arguments_not_null = true;
1658  for (const auto& arg_expr : arg_expr_list) {
1659  if (!arg_expr->get_type_info().get_notnull()) {
1660  arguments_not_null = false;
1661  break;
1662  }
1663  }
1664  ret_ti.set_notnull(arguments_not_null);
1665 
1666  return makeExpr<Analyzer::FunctionOper>(ret_ti, rex_function->getName(), arg_expr_list);
1667 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
auto func_resolve
std::shared_ptr< Analyzer::Expr > translateOffsetInFragment() const
std::shared_ptr< Analyzer::Expr > translateCurrentTimestamp() const
std::shared_ptr< Analyzer::Expr > translateRegexp(const RexFunctionOperator *) const
SQLTypes
Definition: sqltypes.h:37
std::shared_ptr< Analyzer::Expr > translateUnlikely(const RexFunctionOperator *) const
tuple d
Definition: test_fsi.py:9
#define LOG(tag)
Definition: Logger.h:200
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< Analyzer::Expr > translateDateadd(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateAbs(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateItem(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateGeoProjection(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
std::shared_ptr< Analyzer::Expr > translateDatediff(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateSign(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateUnaryGeoFunction(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateLower(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateDatetime(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateCurrentTime() const
int16_t smallintval
Definition: sqltypes.h:207
std::tuple< T, std::vector< SQLTypeInfo > > bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< T > &ext_funcs, const std::string processor)
static std::shared_ptr< Analyzer::Expr > normalize(const SQLOps optype, const SQLQualifier qual, std::shared_ptr< Analyzer::Expr > left_expr, std::shared_ptr< Analyzer::Expr > right_expr)
Definition: ParserNode.cpp:284
Definition: sqltypes.h:51
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
Definition: sqldefs.h:69
std::shared_ptr< Analyzer::Expr > translateArrayFunction(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateCurrentUser(const RexFunctionOperator *) const
bool g_enable_experimental_string_functions
std::shared_ptr< Analyzer::Expr > translateSampleRatio(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateLike(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateGeoBinaryConstructor(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
std::shared_ptr< Analyzer::Expr > translateLikely(const RexFunctionOperator *) const
void set_notnull(bool n)
Definition: sqltypes.h:411
#define CHECK(condition)
Definition: Logger.h:206
std::shared_ptr< Analyzer::Expr > translateTernaryGeoFunction(const RexFunctionOperator *) const
char * t
std::shared_ptr< Analyzer::Expr > translateBinaryGeoFunction(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateFunctionWithGeoArg(const RexFunctionOperator *) const
const std::string & getName() const
std::shared_ptr< Analyzer::Expr > translateCurrentDate() const
std::shared_ptr< Analyzer::Expr > translateCardinality(const RexFunctionOperator *) const
bool is_decimal() const
Definition: sqltypes.h:492
std::shared_ptr< Analyzer::Expr > translateHPTLiteral(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateDatepart(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > rewrite_to_date_trunc(const Analyzer::FunctionOper *dt_plus)
SQLTypeInfo ext_arg_type_to_type_info(const ExtArgumentType ext_arg_type)
std::shared_ptr< Analyzer::Expr > translateKeyForString(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateGeoPredicate(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
std::shared_ptr< Analyzer::Expr > translateLength(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateExtract(const RexFunctionOperator *) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Analyzer::ExpressionPtrVector RelAlgTranslator::translateFunctionArgs ( const RexFunctionOperator rex_function) const
private

Definition at line 1748 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, RexOperator::getOperand(), i, RexOperator::size(), and translateScalarRex().

Referenced by translateArrayFunction(), translateFunction(), translateKeyForString(), and translateLower().

1749  {
1750  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1751  for (size_t i = 0; i < rex_function->size(); ++i) {
1752  args.push_back(translateScalarRex(rex_function->getOperand(i)));
1753  }
1754  return args;
1755 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateFunctionWithGeoArg ( const RexFunctionOperator rex_function) const
private

Definition at line 1479 of file RelAlgTranslatorGeo.cpp.

References run_benchmark_import::args, CHECK, CHECK_EQ, func_resolve, Geospatial::get_compression_scheme(), RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), Datum::intval, kINT, kPOINT, RexOperator::size(), translateGeoFunctionArg(), and translateScalarRex().

Referenced by translateFunction().

1480  {
1481  int32_t lindex = 0;
1482  std::string specialized_geofunc{rex_function->getName()};
1483  if (func_resolve(rex_function->getName(),
1484  "convert_meters_to_pixel_width"sv,
1485  "convert_meters_to_pixel_height"sv)) {
1486  CHECK_EQ(rex_function->size(), 6u);
1487  SQLTypeInfo arg_ti;
1488  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1489  args.push_back(translateScalarRex(rex_function->getOperand(0)));
1490  auto geoargs = translateGeoFunctionArg(
1491  rex_function->getOperand(1), arg_ti, lindex, false, true, false);
1492  // only works on points
1493  if (arg_ti.get_type() != kPOINT) {
1494  throw QueryNotSupported(rex_function->getName() +
1495  " expects a point for the second argument");
1496  }
1497 
1498  args.insert(args.end(), geoargs.begin(), geoargs.begin() + 1);
1499 
1500  // Add compression information
1501  Datum input_compression;
1502  input_compression.intval = Geospatial::get_compression_scheme(arg_ti);
1503  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
1504  if (arg_ti.get_input_srid() != 4326) {
1505  throw QueryNotSupported(
1506  rex_function->getName() +
1507  " currently only supports points of with SRID WGS84/EPSG:4326");
1508  }
1509  Datum input_srid;
1510  input_srid.intval = arg_ti.get_input_srid();
1511  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
1512  Datum output_srid;
1513  // Forcing web-mercator projection for now
1514  // TODO(croot): check that the input-to-output conversion routines exist?
1515  output_srid.intval =
1516  arg_ti.get_output_srid() != 900913 ? 900913 : arg_ti.get_output_srid();
1517  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
1518 
1519  args.push_back(translateScalarRex(rex_function->getOperand(2)));
1520  args.push_back(translateScalarRex(rex_function->getOperand(3)));
1521  args.push_back(translateScalarRex(rex_function->getOperand(4)));
1522  args.push_back(translateScalarRex(rex_function->getOperand(5)));
1523  return makeExpr<Analyzer::FunctionOper>(
1524  rex_function->getType(), specialized_geofunc, args);
1525  } else if (rex_function->getName() == "is_point_in_view"sv) {
1526  CHECK_EQ(rex_function->size(), 5u);
1527  SQLTypeInfo arg_ti;
1528  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1529  auto geoargs = translateGeoFunctionArg(
1530  rex_function->getOperand(0), arg_ti, lindex, false, true, false);
1531  // only works on points
1532  if (arg_ti.get_type() != kPOINT) {
1533  throw QueryNotSupported(rex_function->getName() +
1534  " expects a point for the second argument");
1535  }
1536 
1537  args.insert(args.end(), geoargs.begin(), geoargs.begin() + 1);
1538 
1539  // Add compression information
1540  Datum input_compression;
1541  input_compression.intval = Geospatial::get_compression_scheme(arg_ti);
1542  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
1543  if (arg_ti.get_input_srid() != 4326) {
1544  throw QueryNotSupported(
1545  rex_function->getName() +
1546  " currently only supports points of with SRID WGS84/EPSG:4326");
1547  }
1548  args.push_back(translateScalarRex(rex_function->getOperand(1)));
1549  args.push_back(translateScalarRex(rex_function->getOperand(2)));
1550  args.push_back(translateScalarRex(rex_function->getOperand(3)));
1551  args.push_back(translateScalarRex(rex_function->getOperand(4)));
1552  return makeExpr<Analyzer::FunctionOper>(
1553  rex_function->getType(), specialized_geofunc, args);
1554  } else if (rex_function->getName() == "is_point_size_in_view"sv) {
1555  CHECK_EQ(rex_function->size(), 6u);
1556  SQLTypeInfo arg_ti;
1557  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1558  auto geoargs = translateGeoFunctionArg(
1559  rex_function->getOperand(0), arg_ti, lindex, false, true, false);
1560  // only works on points
1561  if (arg_ti.get_type() != kPOINT) {
1562  throw QueryNotSupported(rex_function->getName() +
1563  " expects a point for the second argument");
1564  }
1565 
1566  args.insert(args.end(), geoargs.begin(), geoargs.begin() + 1);
1567 
1568  // Add compression information
1569  Datum input_compression;
1570  input_compression.intval = Geospatial::get_compression_scheme(arg_ti);
1571  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
1572  if (arg_ti.get_input_srid() != 4326) {
1573  throw QueryNotSupported(
1574  rex_function->getName() +
1575  " currently only supports points of with SRID WGS84/EPSG:4326");
1576  }
1577  args.push_back(translateScalarRex(rex_function->getOperand(1)));
1578  args.push_back(translateScalarRex(rex_function->getOperand(2)));
1579  args.push_back(translateScalarRex(rex_function->getOperand(3)));
1580  args.push_back(translateScalarRex(rex_function->getOperand(4)));
1581  args.push_back(translateScalarRex(rex_function->getOperand(5)));
1582  return makeExpr<Analyzer::FunctionOper>(
1583  rex_function->getType(), specialized_geofunc, args);
1584  }
1585  CHECK(false);
1586  return nullptr;
1587 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
auto func_resolve
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
int32_t intval
Definition: sqltypes.h:208
#define CHECK(condition)
Definition: Logger.h:206
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
Definition: sqltypes.h:44
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateGeoBinaryConstructor ( const RexFunctionOperator rex_function,
SQLTypeInfo ti,
const bool  with_bounds 
) const
private

Definition at line 835 of file RelAlgTranslatorGeo.cpp.

References func_resolve, SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_type(), RexFunctionOperator::getName(), RexOperator::getOperand(), Geospatial::GeoBase::kBUFFER, Geospatial::GeoBase::kDIFFERENCE, kDOUBLE, kENCODING_NONE, Geospatial::GeoBase::kINTERSECTION, kLINESTRING, kMULTIPOLYGON, Geospatial::GeoBase::kUNION, SQLTypeInfo::set_comp_param(), SQLTypeInfo::set_compression(), SQLTypeInfo::set_output_srid(), SQLTypeInfo::set_type(), translateGeoFunctionArg(), and translateScalarRex().

Referenced by translateFunction(), and translateGeoFunctionArg().

838  {
839 #ifndef ENABLE_GEOS
840  throw QueryNotSupported(rex_function->getName() +
841  " geo constructor requires enabled GEOS support");
842 #endif
844  if (rex_function->getName() == "ST_Difference"sv) {
846  } else if (rex_function->getName() == "ST_Union"sv) {
848  } else if (rex_function->getName() == "ST_Buffer"sv) {
850  }
851 
854  SQLTypeInfo arg0_ti;
855  SQLTypeInfo arg1_ti;
856  if (func_resolve(rex_function->getName(),
857  "ST_Intersection"sv,
858  "ST_Difference"sv,
859  "ST_Union"sv,
860  "ST_Buffer"sv)) {
861  // First arg: geometry
862  int32_t lindex0 = 0;
863  geoargs0 = translateGeoFunctionArg(
864  rex_function->getOperand(0), arg0_ti, lindex0, false, false, true, true);
865  if (arg0_ti.get_type() == kLINESTRING) {
866  if (lindex0 != 0) {
867  throw QueryNotSupported(
868  "Indexed LINESTRING geometries not supported in this context");
869  }
870  }
871  }
872  if (func_resolve(rex_function->getName(),
873  "ST_Intersection"sv,
874  "ST_Difference"sv,
875  "ST_Union"sv)) {
876  // Second arg: geometry
877  int32_t lindex1 = 0;
878  geoargs1 = translateGeoFunctionArg(
879  rex_function->getOperand(1), arg1_ti, lindex1, false, false, true, true);
880  if (arg1_ti.get_type() == kLINESTRING) {
881  if (lindex1 != 0) {
882  throw QueryNotSupported(
883  "Indexed LINESTRING geometries not supported in this context");
884  }
885  }
886  } else if (func_resolve(rex_function->getName(), "ST_Buffer"sv)) {
887  // Second arg: double scalar
888  auto param_expr = translateScalarRex(rex_function->getOperand(1));
889  arg1_ti = SQLTypeInfo(kDOUBLE, false);
890  if (param_expr->get_type_info().get_type() != kDOUBLE) {
891  param_expr = param_expr->add_cast(arg1_ti);
892  }
893  geoargs1 = {param_expr};
894  }
895 
896  auto srid = ti.get_output_srid();
897  ti = arg0_ti;
899  ti.set_compression(kENCODING_NONE); // Constructed geometries are not compressed
900  ti.set_comp_param(0);
901  if (srid > 0) {
902  ti.set_output_srid(srid); // Requested SRID sent from above
903  }
904  return makeExpr<Analyzer::GeoBinOper>(op, ti, arg0_ti, arg1_ti, geoargs0, geoargs1);
905 }
void set_compression(EncodingType c)
Definition: sqltypes.h:414
auto func_resolve
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const RexScalar * getOperand(const size_t idx) const
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
void set_output_srid(int s)
Definition: sqltypes.h:410
void set_comp_param(int p)
Definition: sqltypes.h:415
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
std::vector< ExpressionPtr > ExpressionPtrVector
Definition: Analyzer.h:182
const std::string & getName() const
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:320
HOST DEVICE void set_type(SQLTypes t)
Definition: sqltypes.h:404

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< std::shared_ptr< Analyzer::Expr > > RelAlgTranslator::translateGeoColumn ( const RexInput rex_input,
SQLTypeInfo ti,
const bool  with_bounds,
const bool  with_render_group,
const bool  expand_geo_col 
) const
private

Definition at line 26 of file RelAlgTranslatorGeo.cpp.

References run_benchmark_import::args, cat_, CHECK, CHECK_GE, CHECK_LT, ColumnDescriptor::columnType, SQLTypeInfo::get_physical_coord_cols(), SQLTypeInfo::get_type(), RexAbstractInput::getIndex(), Catalog_Namespace::Catalog::getMetadataForColumnBySpi(), RexInput::getSourceNode(), SQLTypeInfo::has_bounds(), SQLTypeInfo::has_render_group(), i, input_to_nest_level_, IS_GEO, and SPIMAP_GEO_PHYSICAL_INPUT.

Referenced by translateBinaryGeoFunction(), translateGeoFunctionArg(), and translateGeoOverlapsOper().

31  {
32  std::vector<std::shared_ptr<Analyzer::Expr>> args;
33  const auto source = rex_input->getSourceNode();
34  const auto it_rte_idx = input_to_nest_level_.find(source);
35  CHECK(it_rte_idx != input_to_nest_level_.end());
36  const int rte_idx = it_rte_idx->second;
37  const auto& in_metainfo = source->getOutputMetainfo();
38 
39  int32_t table_id{0};
40  int column_id{-1};
41  const auto scan_source = dynamic_cast<const RelScan*>(source);
42  if (scan_source) {
43  // We're at leaf (scan) level and not supposed to have input metadata,
44  // the name and type information come directly from the catalog.
45  CHECK(in_metainfo.empty());
46 
47  const auto td = scan_source->getTableDescriptor();
48  table_id = td->tableId;
49 
50  const auto gcd = cat_.getMetadataForColumnBySpi(table_id, rex_input->getIndex() + 1);
51  CHECK(gcd);
52  ti = gcd->columnType;
53  column_id = gcd->columnId;
54 
55  } else {
56  // Likely backed by a temp table. Read the table ID from the source node and negate it
57  // (see RelAlgTranslator::translateInput)
58  table_id = -source->getId();
59 
60  CHECK(!expand_geo_col);
61  if (with_bounds || with_render_group) {
62  throw QueryNotSupported(
63  "Geospatial columns not yet supported in intermediate results.");
64  }
65 
66  CHECK(!in_metainfo.empty());
67  CHECK_GE(rte_idx, 0);
68  column_id = rex_input->getIndex();
69  CHECK_LT(static_cast<size_t>(column_id), in_metainfo.size());
70  ti = in_metainfo[column_id].get_type_info();
71  }
72  CHECK(IS_GEO(ti.get_type()));
73 
74  // Return geo column reference. The geo column may be expanded if required for extension
75  // function arguments. Otherwise, the geo column reference will be translated into
76  // physical columns as required. Bounds column will be added if present and requested.
77  if (expand_geo_col) {
78  for (auto i = 0; i < ti.get_physical_coord_cols(); i++) {
79  const auto pcd = cat_.getMetadataForColumnBySpi(
80  table_id, SPIMAP_GEO_PHYSICAL_INPUT(rex_input->getIndex(), i + 1));
81  auto pcol_ti = pcd->columnType;
82  args.push_back(std::make_shared<Analyzer::ColumnVar>(
83  pcol_ti, table_id, pcd->columnId, rte_idx));
84  }
85  } else {
86  args.push_back(
87  std::make_shared<Analyzer::ColumnVar>(ti, table_id, column_id, rte_idx));
88  }
89  if (with_bounds && ti.has_bounds()) {
90  const auto bounds_cd = cat_.getMetadataForColumnBySpi(
91  table_id,
93  ti.get_physical_coord_cols() + 1));
94  auto bounds_ti = bounds_cd->columnType;
95  args.push_back(std::make_shared<Analyzer::ColumnVar>(
96  bounds_ti, table_id, bounds_cd->columnId, rte_idx));
97  }
98  if (with_render_group && ti.has_render_group()) {
99  const auto render_group_cd = cat_.getMetadataForColumnBySpi(
100  table_id,
101  SPIMAP_GEO_PHYSICAL_INPUT(rex_input->getIndex(),
102  ti.get_physical_coord_cols() + 2));
103  auto render_group_ti = render_group_cd->columnType;
104  args.push_back(std::make_shared<Analyzer::ColumnVar>(
105  render_group_ti, table_id, render_group_cd->columnId, rte_idx));
106  }
107  return args;
108 }
#define SPIMAP_GEO_PHYSICAL_INPUT(c, i)
Definition: Catalog.h:76
#define CHECK_GE(x, y)
Definition: Logger.h:219
unsigned getIndex() const
const ColumnDescriptor * getMetadataForColumnBySpi(const int tableId, const size_t spi) const
Definition: Catalog.cpp:1598
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
#define CHECK_LT(x, y)
Definition: Logger.h:216
const RelAlgNode * getSourceNode() const
#define CHECK(condition)
Definition: Logger.h:206
SQLTypeInfo columnType
#define IS_GEO(T)
Definition: sqltypes.h:245
const Catalog_Namespace::Catalog & cat_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateGeoComparison ( const RexOperator rex_operator) const
private

Definition at line 1450 of file RelAlgTranslatorGeo.cpp.

References RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getOperator(), kLE, and RexOperator::size().

Referenced by translateOper().

1451  {
1452  if (rex_operator->size() != size_t(2)) {
1453  return nullptr;
1454  }
1455 
1456  const auto rex_operand = rex_operator->getOperand(0);
1457  const auto rex_function = dynamic_cast<const RexFunctionOperator*>(rex_operand);
1458  if (!rex_function) {
1459  return nullptr;
1460  }
1461  if (rex_function->getName() == "ST_Distance"sv && rex_operator->getOperator() == kLE) {
1462  // TODO: fixup
1463  return nullptr;
1464  /*
1465  auto ti = rex_operator->getType();
1466  std::vector<std::unique_ptr<const RexScalar>> st_dwithin_operands;
1467  st_dwithin_operands.emplace_back(rex_function->getOperandAndRelease(0));
1468  st_dwithin_operands.emplace_back(rex_function->getOperandAndRelease(1));
1469  st_dwithin_operands.emplace_back(rex_operator->getOperandAndRelease(1));
1470  std::unique_ptr<RexFunctionOperator> st_dwithin(
1471  new RexFunctionOperator("ST_DWithin", st_dwithin_operands, ti));
1472  return translateTernaryGeoFunction(st_dwithin.get());
1473  */
1474  }
1475 
1476  return nullptr;
1477 }
size_t size() const
const RexScalar * getOperand(const size_t idx) const
Definition: sqldefs.h:35
SQLOps getOperator() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< std::shared_ptr< Analyzer::Expr > > RelAlgTranslator::translateGeoFunctionArg ( const RexScalar rex_scalar,
SQLTypeInfo arg_ti,
int32_t &  lindex,
const bool  with_bounds,
const bool  with_render_group,
const bool  expand_geo_col,
const bool  is_projection = false,
const bool  use_geo_expressions = false,
const bool  try_to_compress = false 
) const
private

Definition at line 248 of file RelAlgTranslatorGeo.cpp.

References run_benchmark_import::args, Datum::boolval, CHECK, CHECK_EQ, CHECK_GE, Geospatial::GeoTypesFactory::createGeoType(), fold_expr(), func_resolve, Geospatial::get_compression_scheme(), SQLTypeInfo::get_input_srid(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_subtype(), Analyzer::anonymous_namespace{Analyzer.cpp}::get_ti_from_geo(), SQLTypeInfo::get_type(), i, Datum::intval, IS_GEO, kARRAY, kBOOLEAN, kCAST, kDOUBLE, kENCODING_GEOINT, kENCODING_NONE, kGEOGRAPHY, kGEOMETRY, kINT, kLINESTRING, kNULLT, kPOINT, kSMALLINT, kTEXT, kTINYINT, SQLTypeInfo::set_comp_param(), SQLTypeInfo::set_compression(), SQLTypeInfo::set_input_srid(), SQLTypeInfo::set_notnull(), SQLTypeInfo::set_output_srid(), SQLTypeInfo::set_subtype(), SQLTypeInfo::set_type(), anonymous_namespace{GeoIR.cpp}::suffix(), to_string(), translateGeoBinaryConstructor(), translateGeoColumn(), translateGeoLiteral(), translateGeoPredicate(), translateInput(), translateLiteral(), and translateScalarRex().

Referenced by translateBinaryGeoFunction(), translateFunctionWithGeoArg(), translateGeoBinaryConstructor(), translateGeoPredicate(), translateGeoProjection(), translateTernaryGeoFunction(), and translateUnaryGeoFunction().

257  {
258  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
259 
260  const auto rex_input = dynamic_cast<const RexInput*>(rex_scalar);
261  if (rex_input) {
262  const auto input = translateInput(rex_input);
263  const auto column = dynamic_cast<const Analyzer::ColumnVar*>(input.get());
264  if (!column || !column->get_type_info().is_geometry()) {
265  throw QueryNotSupported("Geo function is expecting a geo column argument");
266  }
267  if (use_geo_expressions) {
268  return {makeExpr<Analyzer::GeoColumnVar>(column, with_bounds, with_render_group)};
269  }
270  return translateGeoColumn(
271  rex_input, arg_ti, with_bounds, with_render_group, expand_geo_col);
272  }
273  const auto rex_function = dynamic_cast<const RexFunctionOperator*>(rex_scalar);
274  if (rex_function) {
275  if (rex_function->getName() == "ST_Transform"sv) {
276  CHECK_EQ(size_t(2), rex_function->size());
277  const auto rex_scalar0 =
278  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
279  if (!rex_scalar0) {
280  throw QueryNotSupported(rex_function->getName() + ": unexpected first argument");
281  }
282 
283  const auto rex_literal =
284  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
285  if (!rex_literal) {
286  throw QueryNotSupported(rex_function->getName() +
287  ": second argument is expected to be a literal");
288  }
289  const auto e = translateLiteral(rex_literal);
290  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
291  if (!ce || !e->get_type_info().is_integer()) {
292  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
293  }
294  int32_t srid = 0;
295  if (e->get_type_info().get_type() == kSMALLINT) {
296  srid = static_cast<int32_t>(ce->get_constval().smallintval);
297  } else if (e->get_type_info().get_type() == kTINYINT) {
298  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
299  } else if (e->get_type_info().get_type() == kINT) {
300  srid = static_cast<int32_t>(ce->get_constval().intval);
301  } else {
302  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
303  }
304  if (srid != 900913) {
305  throw QueryNotSupported(rex_function->getName() + ": unsupported output SRID " +
306  std::to_string(srid));
307  }
308  arg_ti.set_output_srid(srid); // Forward output srid down to argument translation
309  auto arg0 = translateGeoFunctionArg(rex_scalar0,
310  arg_ti,
311  lindex,
312  with_bounds,
313  with_render_group,
314  expand_geo_col,
315  is_projection,
316  use_geo_expressions);
317 
318  if (arg_ti.get_input_srid() > 0) {
319  if (arg_ti.get_input_srid() != 4326) {
320  throw QueryNotSupported(rex_function->getName() + ": unsupported input SRID " +
321  std::to_string(arg_ti.get_input_srid()));
322  }
323  arg_ti.set_output_srid(
324  srid); // We have a valid input SRID, register the output SRID for transform
325  } else {
326  throw QueryNotSupported(rex_function->getName() +
327  ": unexpected input SRID, unable to transform");
328  }
329  return arg0;
330  } else if (func_resolve(
331  rex_function->getName(), "ST_GeomFromText"sv, "ST_GeogFromText"sv)) {
332  CHECK(rex_function->size() == size_t(1) || rex_function->size() == size_t(2));
333  if (use_geo_expressions) {
334  int32_t srid = 0;
335  if (rex_function->size() == 2) {
336  // user supplied srid
337  const auto rex_literal =
338  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
339  if (!rex_literal) {
340  throw QueryNotSupported(rex_function->getName() +
341  ": second argument is expected to be a literal");
342  }
343  const auto e = translateLiteral(rex_literal);
344  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
345  if (!ce || !e->get_type_info().is_integer()) {
346  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
347  }
348  if (e->get_type_info().get_type() == kSMALLINT) {
349  srid = static_cast<int32_t>(ce->get_constval().smallintval);
350  } else if (e->get_type_info().get_type() == kTINYINT) {
351  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
352  } else if (e->get_type_info().get_type() == kINT) {
353  srid = static_cast<int32_t>(ce->get_constval().intval);
354  } else {
355  throw QueryNotSupported(rex_function->getName() + " expecting integer SRID");
356  }
357  if (srid != 0 && srid != 4326 && srid != 900913) {
358  throw QueryNotSupported(rex_function->getName() + ": unsupported SRID " +
359  std::to_string(srid));
360  }
361  }
362  arg_ti.set_input_srid(srid); // Input SRID
363  // leave the output srid unset in case a transform was above us
364  // arg_ti.set_output_srid(srid); // Output SRID is the same - no transform
365 
366  if (rex_function->getName() == "ST_GeogFromText"sv) {
367  arg_ti.set_subtype(kGEOGRAPHY);
368  }
369 
370  auto func_args = translateGeoFunctionArg(rex_function->getOperand(0),
371  arg_ti,
372  lindex,
373  with_bounds,
374  with_render_group,
375  expand_geo_col,
376  is_projection,
377  use_geo_expressions);
378  // TODO: maybe this can be removed?
379  CHECK_GE(func_args.size(), size_t(1));
380  if (auto geo_const =
381  dynamic_cast<const Analyzer::GeoConstant*>(func_args.front().get())) {
382  arg_ti = geo_const->get_type_info();
383  }
384  return func_args;
385  }
386 
387  // First - register srid, then send it to geo literal translation
388  int32_t srid = 0;
389  if (rex_function->size() == 2) {
390  const auto rex_literal =
391  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
392  if (!rex_literal) {
393  throw QueryNotSupported(rex_function->getName() +
394  ": second argument is expected to be a literal");
395  }
396  const auto e = translateLiteral(rex_literal);
397  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
398  if (!ce || !e->get_type_info().is_integer()) {
399  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
400  }
401  if (e->get_type_info().get_type() == kSMALLINT) {
402  srid = static_cast<int32_t>(ce->get_constval().smallintval);
403  } else if (e->get_type_info().get_type() == kTINYINT) {
404  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
405  } else if (e->get_type_info().get_type() == kINT) {
406  srid = static_cast<int32_t>(ce->get_constval().intval);
407  } else {
408  throw QueryNotSupported(rex_function->getName() + " expecting integer SRID");
409  }
410  if (srid != 0 && srid != 4326 && srid != 900913) {
411  throw QueryNotSupported(rex_function->getName() + ": unsupported SRID " +
412  std::to_string(srid));
413  }
414  }
415  arg_ti.set_input_srid(srid); // Input SRID
416  arg_ti.set_output_srid(srid); // Output SRID is the same - no transform
417 
418  const auto rex_literal =
419  dynamic_cast<const RexLiteral*>(rex_function->getOperand(0));
420  if (!rex_literal) {
421  throw QueryNotSupported(rex_function->getName() +
422  " expects a string literal as first argument");
423  }
424  auto arg0 = translateGeoLiteral(rex_literal, arg_ti, with_bounds);
425  arg_ti.set_subtype((rex_function->getName() == "ST_GeogFromText"sv) ? kGEOGRAPHY
426  : kGEOMETRY);
427  return arg0;
428  } else if (rex_function->getName() == "ST_PointN"sv) {
429  if (use_geo_expressions) {
430  std::vector<std::shared_ptr<Analyzer::Expr>> args;
431  for (size_t i = 0; i < rex_function->size(); i++) {
432  // TODO: remove
433  auto constant = dynamic_cast<const RexLiteral*>(rex_function->getOperand(i));
434  if (constant && IS_GEO(constant->getType())) {
435  const auto arg_exprs = translateGeoFunctionArg(constant,
436  arg_ti,
437  lindex,
438  with_bounds,
439  with_render_group,
440  expand_geo_col,
441  is_projection,
442  use_geo_expressions);
443  CHECK_EQ(arg_exprs.size(), size_t(1));
444  args.push_back(arg_exprs.front());
445  } else if (auto function = dynamic_cast<const RexFunctionOperator*>(
446  rex_function->getOperand(i))) {
447  const auto arg_exprs = translateGeoFunctionArg(function,
448  arg_ti,
449  lindex,
450  with_bounds,
451  with_render_group,
452  expand_geo_col,
453  is_projection,
454  use_geo_expressions);
455  CHECK_EQ(arg_exprs.size(), size_t(1));
456  args.push_back(arg_exprs.front());
457  } else {
458  args.push_back(translateScalarRex(rex_function->getOperand(i)));
459  }
460  }
461  arg_ti.set_type(kPOINT);
462  arg_ti.set_notnull(false); // can return null if out of bounds
463  return {makeExpr<Analyzer::GeoOperator>(arg_ti, rex_function->getName(), args)};
464  }
465  CHECK_EQ(size_t(2), rex_function->size());
466  const auto rex_scalar0 =
467  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
468  if (!rex_scalar0) {
469  throw QueryNotSupported(rex_function->getName() +
470  ": expects scalar as first argument");
471  }
472  auto arg0 = translateGeoFunctionArg(
473  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
474  if (arg_ti.get_type() != kLINESTRING) {
475  throw QueryNotSupported(rex_function->getName() +
476  " expects LINESTRING as first argument");
477  }
478  const auto rex_literal =
479  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
480  if (!rex_literal) {
481  throw QueryNotSupported(rex_function->getName() +
482  ": second argument is expected to be a literal");
483  }
484  const auto e = translateLiteral(rex_literal);
485  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
486  if (!ce || !e->get_type_info().is_integer()) {
487  throw QueryNotSupported(rex_function->getName() +
488  ": expecting integer index as second argument");
489  }
490  int32_t index = 0;
491  if (e->get_type_info().get_type() == kSMALLINT) {
492  index = static_cast<int32_t>(ce->get_constval().smallintval);
493  } else if (e->get_type_info().get_type() == kTINYINT) {
494  index = static_cast<int32_t>(ce->get_constval().tinyintval);
495  } else if (e->get_type_info().get_type() == kINT) {
496  index = static_cast<int32_t>(ce->get_constval().intval);
497  } else {
498  throw QueryNotSupported(rex_function->getName() + " expecting integer index");
499  }
500  if (lindex != 0) {
501  throw QueryNotSupported(rex_function->getName() +
502  ": LINESTRING is already indexed");
503  }
504  if (index == 0) {
505  throw QueryNotSupported(rex_function->getName() + ": invalid index");
506  }
507  lindex = index;
508  return arg0;
509  } else if (rex_function->getName() == "ST_StartPoint"sv) {
510  CHECK_EQ(size_t(1), rex_function->size());
511  const auto rex_scalar0 =
512  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
513  if (!rex_scalar0) {
514  throw QueryNotSupported(rex_function->getName() +
515  ": expects scalar as first argument");
516  }
517  auto arg0 = translateGeoFunctionArg(
518  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
519  if (arg_ti.get_type() != kLINESTRING) {
520  throw QueryNotSupported(rex_function->getName() +
521  " expects LINESTRING as first argument");
522  }
523  if (lindex != 0) {
524  throw QueryNotSupported(rex_function->getName() +
525  ": LINESTRING is already indexed");
526  }
527  lindex = 1;
528  return arg0;
529  } else if (rex_function->getName() == "ST_EndPoint"sv) {
530  if (use_geo_expressions) {
531  std::vector<std::shared_ptr<Analyzer::Expr>> args;
532  CHECK_EQ(size_t(1), rex_function->size());
533  // TODO: remove
534  auto constant = dynamic_cast<const RexLiteral*>(rex_function->getOperand(0));
535  if (constant && IS_GEO(constant->getType())) {
536  const auto arg_exprs = translateGeoFunctionArg(constant,
537  arg_ti,
538  lindex,
539  with_bounds,
540  with_render_group,
541  expand_geo_col,
542  is_projection,
543  use_geo_expressions);
544  CHECK_EQ(arg_exprs.size(), size_t(1));
545  args.push_back(arg_exprs.front());
546  } else if (auto function = dynamic_cast<const RexFunctionOperator*>(
547  rex_function->getOperand(0))) {
548  const auto arg_exprs = translateGeoFunctionArg(function,
549  arg_ti,
550  lindex,
551  with_bounds,
552  with_render_group,
553  expand_geo_col,
554  is_projection,
555  use_geo_expressions);
556  CHECK_EQ(arg_exprs.size(), size_t(1));
557  args.push_back(arg_exprs.front());
558  } else {
559  args.push_back(translateScalarRex(rex_function->getOperand(0)));
560  }
561  arg_ti.set_type(kPOINT);
562  return {makeExpr<Analyzer::GeoOperator>(arg_ti, rex_function->getName(), args)};
563  }
564  CHECK_EQ(size_t(1), rex_function->size());
565  const auto rex_scalar0 =
566  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
567  if (!rex_scalar0) {
568  throw QueryNotSupported(rex_function->getName() +
569  ": expects scalar as first argument");
570  }
571  auto arg0 = translateGeoFunctionArg(
572  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
573  if (arg_ti.get_type() != kLINESTRING) {
574  throw QueryNotSupported(rex_function->getName() +
575  " expects LINESTRING as first argument");
576  }
577  if (lindex != 0) {
578  throw QueryNotSupported(rex_function->getName() +
579  ": LINESTRING is already indexed");
580  }
581  lindex = -1;
582  return arg0;
583  } else if (rex_function->getName() == "ST_SRID"sv) {
584  CHECK_EQ(size_t(1), rex_function->size());
585  const auto rex_scalar0 =
586  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
587  if (!rex_scalar0) {
588  throw QueryNotSupported(rex_function->getName() +
589  ": expects scalar as first argument");
590  }
591  auto arg0 = translateGeoFunctionArg(
592  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
593  if (!IS_GEO(arg_ti.get_type())) {
594  throw QueryNotSupported(rex_function->getName() + " expects geometry argument");
595  }
596  return arg0;
597  } else if (rex_function->getName() == "ST_SetSRID"sv) {
598  CHECK_EQ(size_t(2), rex_function->size());
599  const auto rex_literal =
600  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
601  if (!rex_literal) {
602  throw QueryNotSupported(rex_function->getName() +
603  ": second argument is expected to be a literal");
604  }
605  const auto e = translateLiteral(rex_literal);
606  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
607  if (!ce || !e->get_type_info().is_integer()) {
608  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
609  }
610  int32_t srid = 0;
611  if (e->get_type_info().get_type() == kSMALLINT) {
612  srid = static_cast<int32_t>(ce->get_constval().smallintval);
613  } else if (e->get_type_info().get_type() == kTINYINT) {
614  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
615  } else if (e->get_type_info().get_type() == kINT) {
616  srid = static_cast<int32_t>(ce->get_constval().intval);
617  } else {
618  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
619  }
620 
621  const auto rex_scalar0 =
622  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
623  if (!rex_scalar0) {
624  throw QueryNotSupported(rex_function->getName() +
625  ": expects scalar as first argument");
626  }
627  // Only convey the request to compress if dealing with 4326 geo
628  auto arg0 = translateGeoFunctionArg(rex_scalar0,
629  arg_ti,
630  lindex,
631  with_bounds,
632  with_render_group,
633  expand_geo_col,
634  is_projection,
635  false,
636  (try_to_compress && (srid == 4326)));
637  if (!IS_GEO(arg_ti.get_type())) {
638  throw QueryNotSupported(rex_function->getName() + " expects geometry argument");
639  }
640 
641  arg_ti.set_input_srid(srid); // Input SRID
642  arg_ti.set_output_srid(srid); // Output SRID is the same - no transform
643  return arg0;
644  } else if (rex_function->getName() == "CastToGeography"sv) {
645  CHECK_EQ(size_t(1), rex_function->size());
646  const auto rex_scalar0 =
647  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
648  if (!rex_scalar0) {
649  throw QueryNotSupported(rex_function->getName() +
650  ": expects scalar as first argument");
651  }
652  auto arg0 = translateGeoFunctionArg(
653  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
654  if (!IS_GEO(arg_ti.get_type())) {
655  throw QueryNotSupported(rex_function->getName() + " expects geometry argument");
656  }
657  if (arg_ti.get_output_srid() != 4326) {
658  throw QueryNotSupported(rex_function->getName() +
659  " expects geometry with SRID=4326");
660  }
661  arg_ti.set_subtype(kGEOGRAPHY);
662  return arg0;
663  } else if (rex_function->getName() == "ST_Point"sv) {
664  CHECK_EQ(size_t(2), rex_function->size());
665  arg_ti.set_type(kPOINT);
666  arg_ti.set_subtype(kGEOMETRY);
667  arg_ti.set_input_srid(0);
668  arg_ti.set_output_srid(0);
669  arg_ti.set_compression(kENCODING_NONE);
670 
671  auto coord1 = translateScalarRex(rex_function->getOperand(0));
672  auto coord2 = translateScalarRex(rex_function->getOperand(1));
673  auto d_ti = SQLTypeInfo(kDOUBLE, true);
674  auto cast_coord1 = coord1->add_cast(d_ti);
675  auto cast_coord2 = coord2->add_cast(d_ti);
676  // First try to fold to geo literal
677  auto fold1 = fold_expr(cast_coord1.get());
678  auto fold2 = fold_expr(cast_coord2.get());
679  auto const_coord1 = std::dynamic_pointer_cast<Analyzer::Constant>(fold1);
680  auto const_coord2 = std::dynamic_pointer_cast<Analyzer::Constant>(fold2);
681  if (const_coord1 && const_coord2) {
682  CHECK(const_coord1->get_type_info().get_type() == kDOUBLE);
683  CHECK(const_coord2->get_type_info().get_type() == kDOUBLE);
684  std::string wkt = "POINT(" +
685  std::to_string(const_coord1->get_constval().doubleval) + " " +
686  std::to_string(const_coord2->get_constval().doubleval) + ")";
687  RexLiteral rex_literal{wkt, kTEXT, kNULLT, 0, 0, 0, 0};
688  auto args = translateGeoLiteral(&rex_literal, arg_ti, false);
689  CHECK(arg_ti.get_type() == kPOINT);
690  return args;
691  }
692  // Couldn't fold to geo literal, construct [and compress] on the fly
693  auto da_ti = SQLTypeInfo(kARRAY, true);
694  da_ti.set_subtype(kDOUBLE);
695  da_ti.set_size(16);
696  if (try_to_compress) {
697  // Switch to compressed coord array
698  da_ti.set_subtype(kINT);
699  da_ti.set_size(8);
700  da_ti.set_input_srid(4326);
701  da_ti.set_output_srid(4326);
702  da_ti.set_compression(kENCODING_GEOINT);
703  da_ti.set_comp_param(32);
704  // Register point compression
705  arg_ti.set_input_srid(4326);
706  arg_ti.set_output_srid(4326);
707  arg_ti.set_compression(kENCODING_GEOINT);
708  arg_ti.set_comp_param(32);
709  }
710  auto cast_coords = {cast_coord1, cast_coord2};
711  auto is_local_alloca = !is_projection;
712  auto ae = makeExpr<Analyzer::ArrayExpr>(da_ti, cast_coords, false, is_local_alloca);
713  SQLTypeInfo tia_ti = da_ti;
714  tia_ti.set_subtype(kTINYINT);
715  return {makeExpr<Analyzer::UOper>(tia_ti, false, kCAST, ae)};
716  } else if (rex_function->getName() == "ST_Centroid"sv) {
717  CHECK_EQ(size_t(1), rex_function->size());
718  arg_ti.set_type(kPOINT);
719  arg_ti.set_subtype(kGEOMETRY);
720  arg_ti.set_input_srid(0);
721  arg_ti.set_output_srid(0);
722  arg_ti.set_compression(kENCODING_NONE);
723 
724  SQLTypeInfo geo_ti;
725  bool with_bounds = false;
726  auto geoargs = translateGeoFunctionArg(
727  rex_function->getOperand(0), geo_ti, lindex, with_bounds, false, false);
728 
729  auto specialized_geofunc = rex_function->getName() + suffix(geo_ti.get_type());
730  if (lindex != 0) {
731  throw QueryNotSupported(rex_function->getName() +
732  " doesn't support indexed LINESTRINGs");
733  }
734  Datum input_compression;
735  input_compression.intval = Geospatial::get_compression_scheme(geo_ti);
736  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
737  Datum input_srid;
738  input_srid.intval = geo_ti.get_input_srid();
739  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
740  Datum output_srid;
741  output_srid.intval = geo_ti.get_output_srid();
742  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
743 
744  // TODO: find a better way to get 2 coords from the centroid functions
745  Datum coord_selector;
746  coord_selector.boolval = false;
747  geoargs.push_back(makeExpr<Analyzer::Constant>(kBOOLEAN, false, coord_selector));
748  std::shared_ptr<Analyzer::Expr> coord1 = makeExpr<Analyzer::FunctionOper>(
749  rex_function->getType(), specialized_geofunc, geoargs);
750  geoargs.pop_back();
751  coord_selector.boolval = true;
752  geoargs.push_back(makeExpr<Analyzer::Constant>(kBOOLEAN, false, coord_selector));
753  std::shared_ptr<Analyzer::Expr> coord2 = makeExpr<Analyzer::FunctionOper>(
754  rex_function->getType(), specialized_geofunc, geoargs);
755 
756  auto da_ti = SQLTypeInfo(kARRAY, true);
757  da_ti.set_subtype(kDOUBLE);
758  da_ti.set_size(16);
759  auto centroid_coords = {coord1, coord2};
760  auto is_local_alloca = !is_projection;
761  auto ae =
762  makeExpr<Analyzer::ArrayExpr>(da_ti, centroid_coords, false, is_local_alloca);
763  // cast it to tinyint[16]
764  SQLTypeInfo tia_ti = SQLTypeInfo(kARRAY, true);
765  tia_ti.set_subtype(kTINYINT);
766  tia_ti.set_size(16);
767  return {makeExpr<Analyzer::UOper>(tia_ti, false, kCAST, ae)};
768  } else if (func_resolve(rex_function->getName(),
769  "ST_Intersection"sv,
770  "ST_Difference"sv,
771  "ST_Union"sv,
772  "ST_Buffer"sv)) {
773  CHECK_EQ(size_t(2), rex_function->size());
774  // What geo type will the constructor return? Could be anything.
775  return {translateGeoBinaryConstructor(rex_function, arg_ti, with_bounds)};
776  } else if (func_resolve(rex_function->getName(), "ST_IsEmpty"sv, "ST_IsValid"sv)) {
777  CHECK_EQ(size_t(1), rex_function->size());
778  return {translateGeoPredicate(rex_function, arg_ti, with_bounds)};
779  } else {
780  throw QueryNotSupported("Unsupported argument: " + rex_function->getName());
781  }
782  }
783  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
784  if (rex_literal) {
785  if (use_geo_expressions) {
786  const auto translated_literal = translateLiteral(rex_literal);
787  const auto constant_expr =
788  dynamic_cast<const Analyzer::Constant*>(translated_literal.get());
789  CHECK(constant_expr);
790  if (constant_expr->get_is_null()) {
791  // TODO: we could lift this limitation by assuming a minimum type per function
792  throw QueryNotSupported("Geospatial functions require typed nulls.");
793  }
794  const auto& datum = constant_expr->get_constval();
795  CHECK(datum.stringval);
796  auto geospatial_base = Geospatial::GeoTypesFactory::createGeoType(*datum.stringval);
797  CHECK(geospatial_base);
798  SQLTypeInfo ti;
799  ti.set_type(get_ti_from_geo(geospatial_base.get()));
800  if (arg_ti.get_subtype() == kGEOGRAPHY) {
802  } else {
804  }
805  ti.set_input_srid(arg_ti.get_input_srid());
806  ti.set_output_srid(arg_ti.get_output_srid() == 0 ? arg_ti.get_input_srid()
807  : arg_ti.get_output_srid());
808  if (ti.get_output_srid() == 4326) {
810  ti.set_comp_param(32);
811  }
812  ti.set_notnull(true);
813  return {makeExpr<Analyzer::GeoConstant>(std::move(geospatial_base), ti)};
814  }
815  return translateGeoLiteral(rex_literal, arg_ti, with_bounds);
816  }
817  throw QueryNotSupported("Geo function argument not supported");
818 }
void set_compression(EncodingType c)
Definition: sqltypes.h:414
#define CHECK_EQ(x, y)
Definition: Logger.h:214
static std::unique_ptr< GeoBase > createGeoType(const std::string &wkt_or_wkb_hex)
Definition: Types.cpp:919
auto func_resolve
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
int8_t boolval
Definition: sqltypes.h:205
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
HOST DEVICE void set_subtype(SQLTypes st)
Definition: sqltypes.h:405
#define CHECK_GE(x, y)
Definition: Logger.h:219
Definition: sqldefs.h:49
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
std::string to_string(char const *&&v)
std::shared_ptr< Analyzer::Expr > translateInput(const RexInput *) const
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoLiteral(const RexLiteral *, SQLTypeInfo &, bool) const
void set_input_srid(int d)
Definition: sqltypes.h:408
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
void set_output_srid(int s)
Definition: sqltypes.h:410
void set_comp_param(int p)
Definition: sqltypes.h:415
Definition: sqltypes.h:51
std::shared_ptr< Analyzer::Expr > translateGeoBinaryConstructor(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:318
void set_notnull(bool n)
Definition: sqltypes.h:411
#define CHECK(condition)
Definition: Logger.h:206
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
Definition: sqltypes.h:44
std::string suffix(SQLTypes type)
Definition: GeoIR.cpp:156
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoColumn(const RexInput *, SQLTypeInfo &, const bool with_bounds, const bool with_render_group, const bool expand_geo_col) const
#define IS_GEO(T)
Definition: sqltypes.h:245
SQLTypes get_ti_from_geo(const Geospatial::GeoBase *geo)
Definition: Analyzer.cpp:3299
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:320
std::shared_ptr< Analyzer::Expr > translateGeoPredicate(const RexFunctionOperator *, SQLTypeInfo &, const bool with_bounds) const
HOST DEVICE void set_type(SQLTypes t)
Definition: sqltypes.h:404

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< std::shared_ptr< Analyzer::Expr > > RelAlgTranslator::translateGeoLiteral ( const RexLiteral rex_literal,
SQLTypeInfo ti,
bool  with_bounds 
) const
private

Definition at line 110 of file RelAlgTranslatorGeo.cpp.

References run_benchmark_import::args, CHECK, Geospatial::compress_coords(), test_fsi::d, Datum::doubleval, SQLTypeInfo::get_compression(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_type(), Geospatial::GeoTypesFactory::getGeoColumns(), SQLTypeInfo::has_bounds(), Datum::intval, kARRAY, kDOUBLE, kENCODING_GEOINT, kGEOMETRY, kINT, kMULTIPOLYGON, kPOLYGON, kTEXT, kTINYINT, SQLTypeInfo::set_comp_param(), SQLTypeInfo::set_compression(), SQLTypeInfo::set_input_srid(), SQLTypeInfo::set_output_srid(), SQLTypeInfo::set_size(), SQLTypeInfo::set_subtype(), Datum::tinyintval, and translateLiteral().

Referenced by translateGeoFunctionArg().

113  {
114  CHECK(rex_literal);
115  if (rex_literal->getType() != kTEXT) {
116  throw std::runtime_error("Geo literals must be strings");
117  }
118 
119  // TODO: use geo conversion here
120  const auto e = translateLiteral(rex_literal);
121  auto wkt = std::dynamic_pointer_cast<Analyzer::Constant>(e);
122  CHECK(wkt);
123  std::vector<double> coords;
124  std::vector<double> bounds;
125  std::vector<int> ring_sizes;
126  std::vector<int> poly_rings;
127  int32_t srid = ti.get_output_srid();
129  *wkt->get_constval().stringval, ti, coords, bounds, ring_sizes, poly_rings)) {
130  throw QueryNotSupported("Could not read geometry from text");
131  }
133  ti.set_input_srid(srid);
134  ti.set_output_srid(srid);
135  // Compress geo literals by default
136  if (srid == 4326) {
138  ti.set_comp_param(32);
139  }
140 
141  std::vector<std::shared_ptr<Analyzer::Expr>> args;
142 
143  std::vector<uint8_t> compressed_coords = Geospatial::compress_coords(coords, ti);
144  std::list<std::shared_ptr<Analyzer::Expr>> compressed_coords_exprs;
145  for (auto cc : compressed_coords) {
146  Datum d;
147  d.tinyintval = cc;
148  auto e = makeExpr<Analyzer::Constant>(kTINYINT, false, d);
149  compressed_coords_exprs.push_back(e);
150  }
151  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
152  arr_ti.set_subtype(kTINYINT);
153  arr_ti.set_size(compressed_coords.size() * sizeof(int8_t));
154  arr_ti.set_compression(ti.get_compression());
155  arr_ti.set_comp_param((ti.get_compression() == kENCODING_GEOINT) ? 32 : 64);
156  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, compressed_coords_exprs));
157 
158  auto lit_type = ti.get_type();
159  if (lit_type == kPOLYGON || lit_type == kMULTIPOLYGON) {
160  // ring sizes
161  std::list<std::shared_ptr<Analyzer::Expr>> ring_size_exprs;
162  for (auto c : ring_sizes) {
163  Datum d;
164  d.intval = c;
165  auto e = makeExpr<Analyzer::Constant>(kINT, false, d);
166  ring_size_exprs.push_back(e);
167  }
168  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
169  arr_ti.set_subtype(kINT);
170  arr_ti.set_size(ring_sizes.size() * sizeof(int32_t));
171  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, ring_size_exprs));
172 
173  // poly rings
174  if (lit_type == kMULTIPOLYGON) {
175  std::list<std::shared_ptr<Analyzer::Expr>> poly_rings_exprs;
176  for (auto c : poly_rings) {
177  Datum d;
178  d.intval = c;
179  auto e = makeExpr<Analyzer::Constant>(kINT, false, d);
180  poly_rings_exprs.push_back(e);
181  }
182  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
183  arr_ti.set_subtype(kINT);
184  arr_ti.set_size(poly_rings.size() * sizeof(int32_t));
185  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, poly_rings_exprs));
186  }
187  }
188 
189  if (with_bounds && ti.has_bounds()) {
190  // bounds
191  std::list<std::shared_ptr<Analyzer::Expr>> bounds_exprs;
192  for (auto b : bounds) {
193  Datum d;
194  d.doubleval = b;
195  auto e = makeExpr<Analyzer::Constant>(kDOUBLE, false, d);
196  bounds_exprs.push_back(e);
197  }
198  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
199  arr_ti.set_subtype(kDOUBLE);
200  arr_ti.set_size(bounds.size() * sizeof(double));
201  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, bounds_exprs));
202  }
203 
204  return args;
205 }
int8_t tinyintval
Definition: sqltypes.h:206
void set_compression(EncodingType c)
Definition: sqltypes.h:414
void set_size(int s)
Definition: sqltypes.h:412
tuple d
Definition: test_fsi.py:9
HOST DEVICE void set_subtype(SQLTypes st)
Definition: sqltypes.h:405
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
void set_input_srid(int d)
Definition: sqltypes.h:408
std::vector< uint8_t > compress_coords(const std::vector< double > &coords, const SQLTypeInfo &ti)
Definition: Compression.cpp:52
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
bool has_bounds() const
Definition: sqltypes.h:383
void set_output_srid(int s)
Definition: sqltypes.h:410
void set_comp_param(int p)
Definition: sqltypes.h:415
static bool getGeoColumns(const std::string &wkt_or_wkb_hex, SQLTypeInfo &ti, std::vector< double > &coords, std::vector< double > &bounds, std::vector< int > &ring_sizes, std::vector< int > &poly_rings, const bool promote_poly_to_mpoly=false)
Definition: Types.cpp:937
Definition: sqltypes.h:51
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:322
#define CHECK(condition)
Definition: Logger.h:206
Definition: sqltypes.h:44
double doubleval
Definition: sqltypes.h:211
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:320

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateGeoOverlapsOper ( const RexOperator rex_operator) const
private

Definition at line 1589 of file RelAlgTranslatorGeo.cpp.

References CHECK, CHECK_EQ, CHECK_GT, SQLTypeInfo::get_type(), RexOperator::getOperand(), kBOOLEAN, kONE, kOVERLAPS, kPOINT, RexOperator::size(), and translateGeoColumn().

Referenced by translateOverlapsOper().

1590  {
1591  CHECK_EQ(rex_operator->size(), 2u);
1592 
1593  auto translate_input =
1594  [&](const RexScalar* operand) -> std::shared_ptr<Analyzer::Expr> {
1595  const auto input = dynamic_cast<const RexInput*>(operand);
1596  CHECK(input);
1597 
1598  SQLTypeInfo ti;
1599  const auto exprs = translateGeoColumn(input, ti, true, false, false);
1600  CHECK_GT(exprs.size(), 0u);
1601  if (ti.get_type() == kPOINT) {
1602  return exprs.front();
1603  } else {
1604  return exprs.back();
1605  }
1606  };
1607 
1608  SQLQualifier sql_qual{kONE};
1609  SQLOps sql_op{kOVERLAPS};
1610  return makeExpr<Analyzer::BinOper>(SQLTypeInfo(kBOOLEAN, false),
1611  false,
1612  sql_op,
1613  sql_qual,
1614  translate_input(rex_operator->getOperand(1)),
1615  translate_input(rex_operator->getOperand(0)));
1616 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
SQLQualifier
Definition: sqldefs.h:69
size_t size() const
const RexScalar * getOperand(const size_t idx) const
SQLOps
Definition: sqldefs.h:29
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
#define CHECK_GT(x, y)
Definition: Logger.h:218
Definition: sqldefs.h:69
#define CHECK(condition)
Definition: Logger.h:206
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoColumn(const RexInput *, SQLTypeInfo &, const bool with_bounds, const bool with_render_group, const bool expand_geo_col) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateGeoPredicate ( const RexFunctionOperator rex_function,
SQLTypeInfo ti,
const bool  with_bounds 
) const
private

Definition at line 907 of file RelAlgTranslatorGeo.cpp.

References RexFunctionOperator::getName(), RexOperator::getOperand(), kBOOLEAN, Geospatial::GeoBase::kISEMPTY, Geospatial::GeoBase::kISVALID, and translateGeoFunctionArg().

Referenced by translateFunction(), and translateGeoFunctionArg().

910  {
911 #ifndef ENABLE_GEOS
912  throw QueryNotSupported(rex_function->getName() +
913  " geo predicate requires enabled GEOS support");
914 #endif
915  int32_t lindex = 0;
916  SQLTypeInfo arg_ti;
917  auto geoargs = translateGeoFunctionArg(
918  rex_function->getOperand(0), arg_ti, lindex, false, false, true, true);
919  if (lindex != 0) {
920  throw QueryNotSupported(
921  "Indexed LINESTRING geometries not supported in this context");
922  }
923  ti = SQLTypeInfo(kBOOLEAN, false);
924  auto op = (rex_function->getName() == "ST_IsEmpty"sv)
927  return makeExpr<Analyzer::GeoUOper>(op, ti, arg_ti, geoargs);
928 }
const RexScalar * getOperand(const size_t idx) const
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateGeoProjection ( const RexFunctionOperator rex_function,
SQLTypeInfo ti,
const bool  with_bounds 
) const
private

Definition at line 820 of file RelAlgTranslatorGeo.cpp.

References Geospatial::GeoBase::kPROJECTION, and translateGeoFunctionArg().

Referenced by translateFunction().

823  {
824  int32_t lindex = 0;
825  auto geoargs =
826  translateGeoFunctionArg(rex_function, ti, lindex, false, false, true, true);
827  if (lindex != 0) {
828  throw QueryNotSupported(
829  "Indexed LINESTRING geometries not supported in this context");
830  }
831  return makeExpr<Analyzer::GeoUOper>(
832  Geospatial::GeoBase::GeoOp::kPROJECTION, ti, ti, geoargs);
833 }
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateHPTLiteral ( const RexFunctionOperator rex_function) const
private

Definition at line 1800 of file RelAlgTranslator.cpp.

References CHECK_EQ, RexOperator::getOperand(), RexOperator::getType(), RexOperator::size(), to_string(), and translateScalarRex().

Referenced by translateFunction().

1801  {
1802  /* since calcite uses Avatica package called DateTimeUtils to parse timestamp strings.
1803  Therefore any string having fractional seconds more 3 places after the decimal
1804  (milliseconds) will get truncated to 3 decimal places, therefore we lose precision
1805  (us|ns). Issue: [BE-2461] Here we are hijacking literal cast to Timestamp(6|9) from
1806  calcite and translating them to generate our own casts.
1807  */
1808  CHECK_EQ(size_t(1), rex_function->size());
1809  const auto operand = translateScalarRex(rex_function->getOperand(0));
1810  const auto& operand_ti = operand->get_type_info();
1811  const auto& target_ti = rex_function->getType();
1812  if (!operand_ti.is_string()) {
1813  throw std::runtime_error(
1814  "High precision timestamp cast argument must be a string. Input type is: " +
1815  operand_ti.get_type_name());
1816  } else if (!target_ti.is_high_precision_timestamp()) {
1817  throw std::runtime_error(
1818  "Cast target type should be high precision timestamp. Input type is: " +
1819  target_ti.get_type_name());
1820  } else if (target_ti.get_dimension() != 6 && target_ti.get_dimension() != 9) {
1821  throw std::runtime_error(
1822  "Cast target type should be TIMESTAMP(6|9). Input type is: TIMESTAMP(" +
1823  std::to_string(target_ti.get_dimension()) + ")");
1824  } else {
1825  return operand->add_cast(target_ti);
1826  }
1827 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
std::string to_string(char const *&&v)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateInOper ( const RexOperator rex_operator) const
private

Definition at line 547 of file RelAlgTranslator.cpp.

References CHECK, CHECK_EQ, test_fsi::d, anonymous_namespace{RelAlgTranslator.cpp}::datum_from_scalar_tv(), g_enable_watchdog, anonymous_namespace{RelAlgTranslator.cpp}::get_in_values_expr(), getInIntegerSetExpr(), RexOperator::getOperand(), just_explain_, kCAST, kENCODING_DICT, kENCODING_NONE, run_benchmark_import::result, RexOperator::size(), and translateScalarRex().

Referenced by translateOper().

548  {
549  if (just_explain_) {
550  throw std::runtime_error("EXPLAIN is not supported with sub-queries");
551  }
552  CHECK(rex_operator->size() == 2);
553  const auto lhs = translateScalarRex(rex_operator->getOperand(0));
554  const auto rhs = rex_operator->getOperand(1);
555  const auto rex_subquery = dynamic_cast<const RexSubQuery*>(rhs);
556  CHECK(rex_subquery);
557  auto ti = lhs->get_type_info();
558  auto result = rex_subquery->getExecutionResult();
559  CHECK(result);
560  auto& row_set = result->getRows();
561  CHECK_EQ(size_t(1), row_set->colCount());
562  const auto& rhs_ti = row_set->getColType(0);
563  if (rhs_ti.get_type() != ti.get_type()) {
564  throw std::runtime_error(
565  "The two sides of the IN operator must have the same type; found " +
566  ti.get_type_name() + " and " + rhs_ti.get_type_name());
567  }
568  row_set->moveToBegin();
569  if (row_set->entryCount() > 10000) {
570  std::shared_ptr<Analyzer::Expr> expr;
571  if ((ti.is_integer() || (ti.is_string() && ti.get_compression() == kENCODING_DICT)) &&
572  !row_set->getQueryMemDesc().didOutputColumnar()) {
573  expr = getInIntegerSetExpr(lhs, *row_set);
574  // Handle the highly unlikely case when the InIntegerSet ended up being tiny.
575  // Just let it fall through the usual InValues path at the end of this method,
576  // its codegen knows to use inline comparisons for few values.
577  if (expr && std::static_pointer_cast<Analyzer::InIntegerSet>(expr)
578  ->get_value_list()
579  .size() <= 100) {
580  expr = nullptr;
581  }
582  } else {
583  expr = get_in_values_expr(lhs, *row_set);
584  }
585  if (expr) {
586  return expr;
587  }
588  }
589  std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
590  while (true) {
591  auto row = row_set->getNextRow(true, false);
592  if (row.empty()) {
593  break;
594  }
595  if (g_enable_watchdog && value_exprs.size() >= 10000) {
596  throw std::runtime_error(
597  "Unable to handle 'expr IN (subquery)', subquery returned 10000+ rows.");
598  }
599  auto scalar_tv = boost::get<ScalarTargetValue>(&row[0]);
600  Datum d{0};
601  bool is_null_const{false};
602  std::tie(d, is_null_const) = datum_from_scalar_tv(scalar_tv, ti);
603  if (ti.is_string() && ti.get_compression() != kENCODING_NONE) {
604  auto ti_none_encoded = ti;
605  ti_none_encoded.set_compression(kENCODING_NONE);
606  auto none_encoded_string = makeExpr<Analyzer::Constant>(ti, is_null_const, d);
607  auto dict_encoded_string =
608  std::make_shared<Analyzer::UOper>(ti, false, kCAST, none_encoded_string);
609  value_exprs.push_back(dict_encoded_string);
610  } else {
611  value_exprs.push_back(makeExpr<Analyzer::Constant>(ti, is_null_const, d));
612  }
613  }
614  return makeExpr<Analyzer::InValues>(lhs, value_exprs);
615 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
bool g_enable_watchdog
tuple d
Definition: test_fsi.py:9
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
Definition: sqldefs.h:49
std::shared_ptr< Analyzer::Expr > getInIntegerSetExpr(std::shared_ptr< Analyzer::Expr > arg, const ResultSet &val_set) const
std::shared_ptr< Analyzer::Expr > get_in_values_expr(std::shared_ptr< Analyzer::Expr > arg, const ResultSet &val_set)
#define CHECK(condition)
Definition: Logger.h:206
std::pair< Datum, bool > datum_from_scalar_tv(const ScalarTargetValue *scalar_tv, const SQLTypeInfo &ti) noexcept
const bool just_explain_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateInput ( const RexInput rex_input) const
private

Definition at line 374 of file RelAlgTranslator.cpp.

References cat_, CHECK, CHECK_EQ, CHECK_GE, CHECK_LE, CHECK_LT, RexAbstractInput::getIndex(), Catalog_Namespace::Catalog::getMetadataForColumnBySpi(), RelAlgNode::getOutputMetainfo(), RexInput::getSourceNode(), input_to_nest_level_, join_types_, kTEXT, and LEFT.

Referenced by translateGeoFunctionArg(), and translateScalarRex().

375  {
376  const auto source = rex_input->getSourceNode();
377  const auto it_rte_idx = input_to_nest_level_.find(source);
378  CHECK(it_rte_idx != input_to_nest_level_.end())
379  << "Not found in input_to_nest_level_, source=" << source->toString();
380  const int rte_idx = it_rte_idx->second;
381  const auto scan_source = dynamic_cast<const RelScan*>(source);
382  const auto& in_metainfo = source->getOutputMetainfo();
383  if (scan_source) {
384  // We're at leaf (scan) level and not supposed to have input metadata,
385  // the name and type information come directly from the catalog.
386  CHECK(in_metainfo.empty());
387  const auto table_desc = scan_source->getTableDescriptor();
388  const auto cd =
389  cat_.getMetadataForColumnBySpi(table_desc->tableId, rex_input->getIndex() + 1);
390  CHECK(cd);
391  auto col_ti = cd->columnType;
392  if (col_ti.is_string()) {
393  col_ti.set_type(kTEXT);
394  }
395  if (cd->isVirtualCol) {
396  // TODO(alex): remove at some point, we only need this fixup for backwards
397  // compatibility with old imported data
398  CHECK_EQ("rowid", cd->columnName);
399  col_ti.set_size(8);
400  }
401  CHECK_LE(static_cast<size_t>(rte_idx), join_types_.size());
402  if (rte_idx > 0 && join_types_[rte_idx - 1] == JoinType::LEFT) {
403  col_ti.set_notnull(false);
404  }
405  return std::make_shared<Analyzer::ColumnVar>(
406  col_ti, table_desc->tableId, cd->columnId, rte_idx);
407  }
408  CHECK(!in_metainfo.empty()) << "for " << source->toString();
409  CHECK_GE(rte_idx, 0);
410  const size_t col_id = rex_input->getIndex();
411  CHECK_LT(col_id, in_metainfo.size());
412  auto col_ti = in_metainfo[col_id].get_type_info();
413 
414  if (join_types_.size() > 0) {
415  CHECK_LE(static_cast<size_t>(rte_idx), join_types_.size());
416  if (rte_idx > 0 && join_types_[rte_idx - 1] == JoinType::LEFT) {
417  col_ti.set_notnull(false);
418  }
419  }
420 
421  return std::make_shared<Analyzer::ColumnVar>(col_ti, -source->getId(), col_id, rte_idx);
422 }
const std::vector< JoinType > join_types_
#define CHECK_EQ(x, y)
Definition: Logger.h:214
#define CHECK_GE(x, y)
Definition: Logger.h:219
unsigned getIndex() const
const ColumnDescriptor * getMetadataForColumnBySpi(const int tableId, const size_t spi) const
Definition: Catalog.cpp:1598
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
#define CHECK_LT(x, y)
Definition: Logger.h:216
Definition: sqltypes.h:51
#define CHECK_LE(x, y)
Definition: Logger.h:217
const RelAlgNode * getSourceNode() const
#define CHECK(condition)
Definition: Logger.h:206
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
const Catalog_Namespace::Catalog & cat_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateItem ( const RexFunctionOperator rex_function) const
private

Definition at line 1272 of file RelAlgTranslator.cpp.

References CHECK_EQ, RexOperator::getOperand(), kARRAY_AT, kONE, RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

1273  {
1274  CHECK_EQ(size_t(2), rex_function->size());
1275  const auto base = translateScalarRex(rex_function->getOperand(0));
1276  const auto index = translateScalarRex(rex_function->getOperand(1));
1277  return makeExpr<Analyzer::BinOper>(
1278  base->get_type_info().get_elem_type(), false, kARRAY_AT, kONE, base, index);
1279 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
Definition: sqldefs.h:69

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateKeyForString ( const RexFunctionOperator rex_function) const
private

Definition at line 1196 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, CHECK_EQ, RexFunctionOperator::getName(), and translateFunctionArgs().

Referenced by translateFunction().

1197  {
1198  const auto& args = translateFunctionArgs(rex_function);
1199  CHECK_EQ(size_t(1), args.size());
1200  const auto expr = dynamic_cast<Analyzer::Expr*>(args[0].get());
1201  if (nullptr == expr || !expr->get_type_info().is_string() ||
1202  expr->get_type_info().is_varlen()) {
1203  throw std::runtime_error(rex_function->getName() +
1204  " expects a dictionary encoded text column.");
1205  }
1206  return makeExpr<Analyzer::KeyForStringExpr>(args[0]);
1207 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateLength ( const RexFunctionOperator rex_function) const
private

Definition at line 1188 of file RelAlgTranslator.cpp.

References CHECK_EQ, RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

1189  {
1190  CHECK_EQ(size_t(1), rex_function->size());
1191  const auto str_arg = translateScalarRex(rex_function->getOperand(0));
1192  return makeExpr<Analyzer::CharLengthExpr>(str_arg->decompress(),
1193  rex_function->getName() == "CHAR_LENGTH"sv);
1194 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateLike ( const RexFunctionOperator rex_function) const
private

Definition at line 937 of file RelAlgTranslator.cpp.

References CHECK, Parser::LikeExpr::get(), RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

938  {
939  CHECK(rex_function->size() == 2 || rex_function->size() == 3);
940  const auto arg = translateScalarRex(rex_function->getOperand(0));
941  const auto like = translateScalarRex(rex_function->getOperand(1));
942  if (!std::dynamic_pointer_cast<const Analyzer::Constant>(like)) {
943  throw std::runtime_error("The matching pattern must be a literal.");
944  }
945  const auto escape = (rex_function->size() == 3)
946  ? translateScalarRex(rex_function->getOperand(2))
947  : nullptr;
948  const bool is_ilike = rex_function->getName() == "PG_ILIKE"sv;
949  return Parser::LikeExpr::get(arg, like, escape, is_ilike, false);
950 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
static std::shared_ptr< Analyzer::Expr > get(std::shared_ptr< Analyzer::Expr > arg_expr, std::shared_ptr< Analyzer::Expr > like_expr, std::shared_ptr< Analyzer::Expr > escape_expr, const bool is_ilike, const bool is_not)
Definition: ParserNode.cpp:559
#define CHECK(condition)
Definition: Logger.h:206
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateLikely ( const RexFunctionOperator rex_function) const
private

Definition at line 966 of file RelAlgTranslator.cpp.

References CHECK, RexOperator::getOperand(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

967  {
968  CHECK(rex_function->size() == 1);
969  const auto arg = translateScalarRex(rex_function->getOperand(0));
970  return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.9375);
971 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
#define CHECK(condition)
Definition: Logger.h:206

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateLiteral ( const RexLiteral rex_literal)
static

Definition at line 262 of file RelAlgTranslator.cpp.

References Parser::StringLiteral::analyzeValue(), Parser::IntLiteral::analyzeValue(), Parser::FixedPtLiteral::analyzeValue(), run_benchmark_import::args, Datum::bigintval, Datum::boolval, anonymous_namespace{RelAlgTranslator.cpp}::build_type_info(), test_fsi::d, Datum::doubleval, logger::FATAL, kBIGINT, kBOOLEAN, kDATE, kDECIMAL, kDOUBLE, kINT, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kNULLT, kTEXT, kTIME, kTIMESTAMP, LOG, and make_fp_constant().

Referenced by ResultSetLogicalValuesBuilder::build(), translateGeoFunctionArg(), translateGeoLiteral(), and translateScalarRex().

263  {
264  auto lit_ti = build_type_info(
265  rex_literal->getType(), rex_literal->getScale(), rex_literal->getPrecision());
266  auto target_ti = build_type_info(rex_literal->getTargetType(),
267  rex_literal->getTypeScale(),
268  rex_literal->getTypePrecision());
269  switch (rex_literal->getType()) {
270  case kINT:
271  case kBIGINT: {
272  Datum d;
273  d.bigintval = rex_literal->getVal<int64_t>();
274  return makeExpr<Analyzer::Constant>(rex_literal->getType(), false, d);
275  }
276  case kDECIMAL: {
277  const auto val = rex_literal->getVal<int64_t>();
278  const int precision = rex_literal->getPrecision();
279  const int scale = rex_literal->getScale();
280  if (target_ti.is_fp() && !scale) {
281  return make_fp_constant(val, target_ti);
282  }
283  auto lit_expr = scale ? Parser::FixedPtLiteral::analyzeValue(val, scale, precision)
284  : Parser::IntLiteral::analyzeValue(val);
285  return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
286  }
287  case kTEXT: {
288  return Parser::StringLiteral::analyzeValue(rex_literal->getVal<std::string>());
289  }
290  case kBOOLEAN: {
291  Datum d;
292  d.boolval = rex_literal->getVal<bool>();
293  return makeExpr<Analyzer::Constant>(kBOOLEAN, false, d);
294  }
295  case kDOUBLE: {
296  Datum d;
297  d.doubleval = rex_literal->getVal<double>();
298  auto lit_expr = makeExpr<Analyzer::Constant>(kDOUBLE, false, d);
299  return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
300  }
301  case kINTERVAL_DAY_TIME:
302  case kINTERVAL_YEAR_MONTH: {
303  Datum d;
304  d.bigintval = rex_literal->getVal<int64_t>();
305  return makeExpr<Analyzer::Constant>(rex_literal->getType(), false, d);
306  }
307  case kTIME:
308  case kTIMESTAMP: {
309  Datum d;
310  d.bigintval =
311  rex_literal->getType() == kTIMESTAMP && rex_literal->getPrecision() > 0
312  ? rex_literal->getVal<int64_t>()
313  : rex_literal->getVal<int64_t>() / 1000;
314  return makeExpr<Analyzer::Constant>(
315  SQLTypeInfo(rex_literal->getType(), rex_literal->getPrecision(), 0, false),
316  false,
317  d);
318  }
319  case kDATE: {
320  Datum d;
321  d.bigintval = rex_literal->getVal<int64_t>() * 24 * 3600;
322  return makeExpr<Analyzer::Constant>(rex_literal->getType(), false, d);
323  }
324  case kNULLT: {
325  if (target_ti.is_array()) {
327  // defaulting to valid sub-type for convenience
328  target_ti.set_subtype(kBOOLEAN);
329  return makeExpr<Analyzer::ArrayExpr>(target_ti, args, true);
330  }
331  return makeExpr<Analyzer::Constant>(rex_literal->getTargetType(), true, Datum{0});
332  }
333  default: {
334  LOG(FATAL) << "Unexpected literal type " << lit_ti.get_type_name();
335  }
336  }
337  return nullptr;
338 }
Definition: sqltypes.h:48
tuple d
Definition: test_fsi.py:9
#define LOG(tag)
Definition: Logger.h:200
int8_t boolval
Definition: sqltypes.h:205
int64_t bigintval
Definition: sqltypes.h:209
SQLTypeInfo build_type_info(const SQLTypes sql_type, const int scale, const int precision)
static std::shared_ptr< Analyzer::Expr > analyzeValue(const std::string &)
Definition: ParserNode.cpp:118
Definition: sqltypes.h:51
Definition: sqltypes.h:52
static std::shared_ptr< Analyzer::Expr > analyzeValue(const int64_t numericval, const int scale, const int precision)
Definition: ParserNode.cpp:158
std::shared_ptr< Analyzer::Constant > make_fp_constant(const int64_t val, const SQLTypeInfo &ti)
std::vector< ExpressionPtr > ExpressionPtrVector
Definition: Analyzer.h:182
Definition: sqltypes.h:44
double doubleval
Definition: sqltypes.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateLower ( const RexFunctionOperator rex_function) const
private

Definition at line 1230 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, CHECK, CHECK_EQ, RexFunctionOperator::getName(), and translateFunctionArgs().

Referenced by translateFunction().

1231  {
1232  const auto& args = translateFunctionArgs(rex_function);
1233  CHECK_EQ(size_t(1), args.size());
1234  CHECK(args[0]);
1235 
1236  if (args[0]->get_type_info().is_dict_encoded_string() ||
1237  dynamic_cast<Analyzer::Constant*>(args[0].get())) {
1238  return makeExpr<Analyzer::LowerExpr>(args[0]);
1239  }
1240 
1241  throw std::runtime_error(rex_function->getName() +
1242  " expects a dictionary encoded text column or a literal.");
1243 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
#define CHECK(condition)
Definition: Logger.h:206
const std::string & getName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateOffsetInFragment ( ) const
private

Definition at line 1353 of file RelAlgTranslator.cpp.

Referenced by translateFunction().

1353  {
1354  return makeExpr<Analyzer::OffsetInFragment>();
1355 }

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateOper ( const RexOperator rex_operator) const
private

Definition at line 867 of file RelAlgTranslator.cpp.

References CHECK, CHECK_GT, anonymous_namespace{RelAlgTranslator.cpp}::get_quantified_rhs(), RexOperator::getOperand(), RexOperator::getOperator(), i, IS_COMPARISON, kIN, kMINUS, kONE, kOVERLAPS, kPLUS, Parser::OperExpr::normalize(), RexOperator::size(), translateDatePlusMinus(), translateGeoComparison(), translateInOper(), translateOverlapsOper(), translateScalarRex(), and translateUoper().

Referenced by translateScalarRex().

868  {
869  CHECK_GT(rex_operator->size(), size_t(0));
870  if (rex_operator->size() == 1) {
871  return translateUoper(rex_operator);
872  }
873  const auto sql_op = rex_operator->getOperator();
874  if (sql_op == kIN) {
875  return translateInOper(rex_operator);
876  }
877  if (sql_op == kMINUS || sql_op == kPLUS) {
878  auto date_plus_minus = translateDatePlusMinus(rex_operator);
879  if (date_plus_minus) {
880  return date_plus_minus;
881  }
882  }
883  if (sql_op == kOVERLAPS) {
884  return translateOverlapsOper(rex_operator);
885  } else if (IS_COMPARISON(sql_op)) {
886  auto geo_comp = translateGeoComparison(rex_operator);
887  if (geo_comp) {
888  return geo_comp;
889  }
890  }
891  auto lhs = translateScalarRex(rex_operator->getOperand(0));
892  for (size_t i = 1; i < rex_operator->size(); ++i) {
893  std::shared_ptr<Analyzer::Expr> rhs;
894  SQLQualifier sql_qual{kONE};
895  const auto rhs_op = rex_operator->getOperand(i);
896  std::tie(rhs, sql_qual) = get_quantified_rhs(rhs_op, *this);
897  if (!rhs) {
898  rhs = translateScalarRex(rhs_op);
899  }
900  CHECK(rhs);
901  lhs = Parser::OperExpr::normalize(sql_op, sql_qual, lhs, rhs);
902  }
903  return lhs;
904 }
SQLQualifier
Definition: sqldefs.h:69
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< Analyzer::Expr > translateUoper(const RexOperator *) const
Definition: sqldefs.h:41
#define CHECK_GT(x, y)
Definition: Logger.h:218
SQLOps getOperator() const
static std::shared_ptr< Analyzer::Expr > normalize(const SQLOps optype, const SQLQualifier qual, std::shared_ptr< Analyzer::Expr > left_expr, std::shared_ptr< Analyzer::Expr > right_expr)
Definition: ParserNode.cpp:284
std::pair< std::shared_ptr< Analyzer::Expr >, SQLQualifier > get_quantified_rhs(const RexScalar *rex_scalar, const RelAlgTranslator &translator)
Definition: sqldefs.h:40
Definition: sqldefs.h:69
std::shared_ptr< Analyzer::Expr > translateOverlapsOper(const RexOperator *) const
Definition: sqldefs.h:53
#define CHECK(condition)
Definition: Logger.h:206
std::shared_ptr< Analyzer::Expr > translateInOper(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateGeoComparison(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateDatePlusMinus(const RexOperator *) const
#define IS_COMPARISON(X)
Definition: sqldefs.h:57

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateOverlapsOper ( const RexOperator rex_operator) const
private

Definition at line 906 of file RelAlgTranslator.cpp.

References CHECK, RexOperator::getOperand(), RexOperator::getOperator(), kOVERLAPS, translateGeoOverlapsOper(), and translateScalarRex().

Referenced by translateOper().

907  {
908  const auto sql_op = rex_operator->getOperator();
909  CHECK(sql_op == kOVERLAPS);
910 
911  const auto lhs = translateScalarRex(rex_operator->getOperand(0));
912  const auto lhs_ti = lhs->get_type_info();
913  if (lhs_ti.is_geometry()) {
914  return translateGeoOverlapsOper(rex_operator);
915  } else {
916  throw std::runtime_error(
917  "Overlaps equivalence is currently only supported for geospatial types");
918  }
919 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< Analyzer::Expr > translateGeoOverlapsOper(const RexOperator *) const
SQLOps getOperator() const
#define CHECK(condition)
Definition: Logger.h:206

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateRegexp ( const RexFunctionOperator rex_function) const
private

Definition at line 952 of file RelAlgTranslator.cpp.

References CHECK, Parser::RegexpExpr::get(), RexOperator::getOperand(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

953  {
954  CHECK(rex_function->size() == 2 || rex_function->size() == 3);
955  const auto arg = translateScalarRex(rex_function->getOperand(0));
956  const auto pattern = translateScalarRex(rex_function->getOperand(1));
957  if (!std::dynamic_pointer_cast<const Analyzer::Constant>(pattern)) {
958  throw std::runtime_error("The matching pattern must be a literal.");
959  }
960  const auto escape = (rex_function->size() == 3)
961  ? translateScalarRex(rex_function->getOperand(2))
962  : nullptr;
963  return Parser::RegexpExpr::get(arg, pattern, escape, false);
964 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
static std::shared_ptr< Analyzer::Expr > get(std::shared_ptr< Analyzer::Expr > arg_expr, std::shared_ptr< Analyzer::Expr > pattern_expr, std::shared_ptr< Analyzer::Expr > escape_expr, const bool is_not)
Definition: ParserNode.cpp:654
#define CHECK(condition)
Definition: Logger.h:206

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateSampleRatio ( const RexFunctionOperator rex_function) const
private

Definition at line 1209 of file RelAlgTranslator.cpp.

References CHECK_EQ, RexOperator::getOperand(), kDOUBLE, RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

1210  {
1211  CHECK_EQ(size_t(1), rex_function->size());
1212  auto arg = translateScalarRex(rex_function->getOperand(0));
1213  const auto& arg_ti = arg->get_type_info();
1214  if (arg_ti.get_type() != kDOUBLE) {
1215  const auto& double_ti = SQLTypeInfo(kDOUBLE, arg_ti.get_notnull());
1216  arg = arg->add_cast(double_ti);
1217  }
1218  return makeExpr<Analyzer::SampleRatioExpr>(arg);
1219 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateScalarRex ( const RexScalar rex) const

Definition at line 178 of file RelAlgTranslator.cpp.

References CHECK, translateCase(), translateFunction(), translateInput(), translateLiteral(), translateOper(), translateScalarSubquery(), and translateWindowFunction().

Referenced by anonymous_namespace{RelAlgExecutor.cpp}::get_inputs_meta(), anonymous_namespace{RelAlgTranslator.cpp}::get_quantified_rhs(), RelAlgExecutor::makeJoinQuals(), anonymous_namespace{RelAlgExecutor.cpp}::translate_quals(), anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources(), anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources_for_update(), anonymous_namespace{RelAlgExecutor.cpp}::translate_targets(), translateAbs(), translateBinaryGeoFunction(), translateCardinality(), translateCase(), translateDateadd(), translateDatediff(), translateDatepart(), translateDatePlusMinus(), translateDatetime(), translateExtract(), translateFunction(), translateFunctionArgs(), translateFunctionWithGeoArg(), translateGeoBinaryConstructor(), translateGeoFunctionArg(), translateHPTLiteral(), translateInOper(), translateItem(), translateLength(), translateLike(), translateLikely(), translateOper(), translateOverlapsOper(), translateRegexp(), translateSampleRatio(), translateSign(), translateTernaryGeoFunction(), translateUnlikely(), translateUoper(), and translateWindowFunction().

179  {
180  const auto rex_input = dynamic_cast<const RexInput*>(rex);
181  if (rex_input) {
182  return translateInput(rex_input);
183  }
184  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex);
185  if (rex_literal) {
186  return translateLiteral(rex_literal);
187  }
188  const auto rex_window_function = dynamic_cast<const RexWindowFunctionOperator*>(rex);
189  if (rex_window_function) {
190  return translateWindowFunction(rex_window_function);
191  }
192  const auto rex_function = dynamic_cast<const RexFunctionOperator*>(rex);
193  if (rex_function) {
194  return translateFunction(rex_function);
195  }
196  const auto rex_operator = dynamic_cast<const RexOperator*>(rex);
197  if (rex_operator) {
198  return translateOper(rex_operator);
199  }
200  const auto rex_case = dynamic_cast<const RexCase*>(rex);
201  if (rex_case) {
202  return translateCase(rex_case);
203  }
204  const auto rex_subquery = dynamic_cast<const RexSubQuery*>(rex);
205  if (rex_subquery) {
206  return translateScalarSubquery(rex_subquery);
207  }
208  CHECK(false);
209  return nullptr;
210 }
std::shared_ptr< Analyzer::Expr > translateFunction(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateOper(const RexOperator *) const
std::shared_ptr< Analyzer::Expr > translateInput(const RexInput *) const
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
#define CHECK(condition)
Definition: Logger.h:206
std::shared_ptr< Analyzer::Expr > translateCase(const RexCase *) const
std::shared_ptr< Analyzer::Expr > translateWindowFunction(const RexWindowFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateScalarSubquery(const RexSubQuery *) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateScalarSubquery ( const RexSubQuery rex_subquery) const
private

Definition at line 340 of file RelAlgTranslator.cpp.

References CHECK, CHECK_EQ, test_fsi::d, anonymous_namespace{RelAlgTranslator.cpp}::datum_from_scalar_tv(), just_explain_, and run_benchmark_import::result.

Referenced by translateScalarRex().

341  {
342  if (just_explain_) {
343  throw std::runtime_error("EXPLAIN is not supported with sub-queries");
344  }
345  CHECK(rex_subquery);
346  auto result = rex_subquery->getExecutionResult();
347  auto row_set = result->getRows();
348  const size_t row_count = row_set->rowCount();
349  if (row_count > size_t(1)) {
350  throw std::runtime_error("Scalar sub-query returned multiple rows");
351  }
352  if (row_count == size_t(0)) {
353  if (row_set->isValidationOnlyRes()) {
354  Datum d{0};
355  return makeExpr<Analyzer::Constant>(rex_subquery->getType(), false, d);
356  }
357  throw std::runtime_error("Scalar sub-query returned no results");
358  }
359  CHECK_EQ(row_count, size_t(1));
360  row_set->moveToBegin();
361  auto first_row = row_set->getNextRow(false, false);
362  CHECK_EQ(first_row.size(), size_t(1));
363  auto scalar_tv = boost::get<ScalarTargetValue>(&first_row[0]);
364  auto ti = rex_subquery->getType();
365  if (ti.is_string()) {
366  throw std::runtime_error("Scalar sub-queries which return strings not supported");
367  }
368  Datum d{0};
369  bool is_null_const{false};
370  std::tie(d, is_null_const) = datum_from_scalar_tv(scalar_tv, ti);
371  return makeExpr<Analyzer::Constant>(ti, is_null_const, d);
372 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
tuple d
Definition: test_fsi.py:9
#define CHECK(condition)
Definition: Logger.h:206
std::pair< Datum, bool > datum_from_scalar_tv(const ScalarTargetValue *scalar_tv, const SQLTypeInfo &ti) noexcept
const bool just_explain_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateSign ( const RexFunctionOperator rex_function) const
private

Definition at line 1331 of file RelAlgTranslator.cpp.

References CHECK, CHECK_EQ, RexOperator::getOperand(), kBOOLEAN, kEQ, kGT, kLT, kONE, anonymous_namespace{RelAlgTranslator.cpp}::makeNumericConstant(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

1332  {
1333  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1334  expr_list;
1335  CHECK_EQ(size_t(1), rex_function->size());
1336  const auto operand = translateScalarRex(rex_function->getOperand(0));
1337  const auto& operand_ti = operand->get_type_info();
1338  CHECK(operand_ti.is_number());
1339  const auto zero = makeNumericConstant(operand_ti, 0);
1340  const auto lt_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kLT, kONE, operand, zero);
1341  expr_list.emplace_back(lt_zero, makeNumericConstant(operand_ti, -1));
1342  const auto eq_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kEQ, kONE, operand, zero);
1343  expr_list.emplace_back(eq_zero, makeNumericConstant(operand_ti, 0));
1344  const auto gt_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kGT, kONE, operand, zero);
1345  expr_list.emplace_back(gt_zero, makeNumericConstant(operand_ti, 1));
1346  return makeExpr<Analyzer::CaseExpr>(
1347  operand_ti,
1348  false,
1349  expr_list,
1350  makeExpr<Analyzer::Constant>(operand_ti, true, Datum{0}));
1351 }
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
Definition: sqldefs.h:30
std::shared_ptr< Analyzer::Constant > makeNumericConstant(const SQLTypeInfo &ti, const long val)
Definition: sqldefs.h:34
Definition: sqldefs.h:69
#define CHECK(condition)
Definition: Logger.h:206
Definition: sqldefs.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateTernaryGeoFunction ( const RexFunctionOperator rex_function) const
private

Definition at line 1345 of file RelAlgTranslatorGeo.cpp.

References CHECK_EQ, Geospatial::get_compression_scheme(), SQLTypeInfo::get_input_srid(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_subtype(), SQLTypeInfo::get_type(), RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), Datum::intval, kBOOLEAN, kDOUBLE, kGEOMETRY, kINT, kLE, kLINESTRING, kMULTIPOLYGON, kONE, kPOINT, kPOLYGON, run_benchmark_import::result, RexOperator::size(), anonymous_namespace{GeoIR.cpp}::suffix(), translateBinaryGeoFunction(), translateGeoFunctionArg(), and translateScalarRex().

Referenced by translateFunction().

1346  {
1347  CHECK_EQ(size_t(3), rex_function->size());
1348 
1349  auto distance_expr = translateScalarRex(rex_function->getOperand(2));
1350  const auto& distance_ti = SQLTypeInfo(kDOUBLE, false);
1351  if (distance_expr->get_type_info().get_type() != kDOUBLE) {
1352  distance_expr = distance_expr->add_cast(distance_ti);
1353  }
1354 
1355  auto function_name = rex_function->getName();
1356  if (function_name == "ST_DWithin"sv) {
1357  auto return_type = rex_function->getType();
1358  bool swap_args = false;
1359  bool with_bounds = true;
1360  SQLTypeInfo arg0_ti;
1361  SQLTypeInfo arg1_ti;
1362  int32_t lindex0 = 0;
1363  int32_t lindex1 = 0;
1364 
1365  auto geoargs0 = translateGeoFunctionArg(
1366  rex_function->getOperand(0), arg0_ti, lindex0, with_bounds, false, false);
1367  if (arg0_ti.get_type() == kLINESTRING) {
1368  Datum index;
1369  index.intval = lindex0;
1370  geoargs0.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
1371  }
1372  auto geoargs1 = translateGeoFunctionArg(
1373  rex_function->getOperand(1), arg1_ti, lindex1, with_bounds, false, false);
1374  if (arg1_ti.get_type() == kLINESTRING) {
1375  Datum index;
1376  index.intval = lindex1;
1377  geoargs1.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
1378  }
1379  if (arg0_ti.get_subtype() == kGEOMETRY &&
1380  arg0_ti.get_subtype() != arg1_ti.get_subtype()) {
1381  throw QueryNotSupported(rex_function->getName() +
1382  " accepts only accepts GEOMETRY arguments");
1383  }
1384  // Check SRID match if at least one is set/valid
1385  if ((arg0_ti.get_output_srid() > 0 || arg1_ti.get_output_srid() > 0) &&
1386  arg0_ti.get_output_srid() != arg1_ti.get_output_srid()) {
1387  throw QueryNotSupported(rex_function->getName() + " cannot accept different SRIDs");
1388  }
1389 
1390  if ((arg1_ti.get_type() == kPOINT && arg0_ti.get_type() != kPOINT) ||
1391  (arg1_ti.get_type() == kLINESTRING && arg0_ti.get_type() == kPOLYGON) ||
1392  (arg1_ti.get_type() == kPOLYGON && arg0_ti.get_type() == kMULTIPOLYGON)) {
1393  // Swap arguments and use single implementation per arg pair
1394  swap_args = true;
1395  }
1396 
1397  // First input's compression mode and SRID args to enable on-the-fly
1398  // decompression/transforms
1399  Datum input_compression0;
1400  input_compression0.intval = Geospatial::get_compression_scheme(arg0_ti);
1401  Datum input_srid0;
1402  input_srid0.intval = arg0_ti.get_input_srid();
1403 
1404  // Second input's compression mode and SRID args to enable on-the-fly
1405  // decompression/transforms
1406  Datum input_compression1;
1407  input_compression1.intval = Geospatial::get_compression_scheme(arg1_ti);
1408  Datum input_srid1;
1409  input_srid1.intval = arg1_ti.get_input_srid();
1410 
1411  // Output SRID arg to enable on-the-fly transforms
1412  Datum output_srid;
1413  output_srid.intval = arg0_ti.get_output_srid();
1414 
1415  std::string specialized_geofunc{function_name};
1416  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
1417  if (swap_args) {
1418  specialized_geofunc += suffix(arg1_ti.get_type()) + suffix(arg0_ti.get_type());
1419  geoargs.insert(geoargs.end(), geoargs1.begin(), geoargs1.end());
1420  geoargs.insert(geoargs.end(), geoargs0.begin(), geoargs0.end());
1421  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression1));
1422  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid1));
1423  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression0));
1424  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid0));
1425  } else {
1426  specialized_geofunc += suffix(arg0_ti.get_type()) + suffix(arg1_ti.get_type());
1427  geoargs.insert(geoargs.end(), geoargs0.begin(), geoargs0.end());
1428  geoargs.insert(geoargs.end(), geoargs1.begin(), geoargs1.end());
1429  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression0));
1430  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid0));
1431  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression1));
1432  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid1));
1433  }
1434  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
1435  // Also add the within distance
1436  geoargs.push_back(distance_expr);
1437 
1438  auto result =
1439  makeExpr<Analyzer::FunctionOper>(return_type, specialized_geofunc, geoargs);
1440  return result;
1441  }
1442 
1443  // Otherwise translate function as binary geo to get distance,
1444  // with optional short-circuiting threshold held in the third operand
1445  const auto geo_distance = translateBinaryGeoFunction(rex_function);
1446  // and generate the comparison
1447  return makeExpr<Analyzer::BinOper>(kBOOLEAN, kLE, kONE, geo_distance, distance_expr);
1448 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:315
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
Definition: sqldefs.h:35
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
Definition: sqldefs.h:69
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:318
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
std::shared_ptr< Analyzer::Expr > translateBinaryGeoFunction(const RexFunctionOperator *) const
Definition: sqltypes.h:44
const std::string & getName() const
std::string suffix(SQLTypes type)
Definition: GeoIR.cpp:156
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:320

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateUnaryGeoFunction ( const RexFunctionOperator rex_function) const
private

Definition at line 930 of file RelAlgTranslatorGeo.cpp.

References CHECK_EQ, func_resolve, Geospatial::get_compression_scheme(), SQLTypeInfo::get_input_srid(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_subtype(), SQLTypeInfo::get_type(), RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), SQLTypeInfo::has_bounds(), Datum::intval, IS_GEO_POLY, kGEOGRAPHY, kINT, kLINESTRING, kMULTIPOLYGON, kPOINT, kPOLYGON, SQLTypeInfo::set_notnull(), RexOperator::size(), anonymous_namespace{GeoIR.cpp}::suffix(), and translateGeoFunctionArg().

Referenced by translateFunction().

931  {
932  CHECK_EQ(size_t(1), rex_function->size());
933 
934  int32_t lindex = 0;
935  std::string specialized_geofunc{rex_function->getName()};
936 
937  // Geo function calls which do not need the coords col but do need cols associated
938  // with physical coords (e.g. ring_sizes / poly_rings)
939  if (rex_function->getName() == "ST_NRings"sv) {
940  SQLTypeInfo arg_ti;
941  auto geoargs = translateGeoFunctionArg(rex_function->getOperand(0),
942  arg_ti,
943  lindex,
944  /*with_bounds=*/false,
945  /*with_render_group=*/false,
946  /*expand_geo_col=*/true,
947  /*is_projection=*/false,
948  /*use_geo_expressions=*/true);
949  CHECK_EQ(geoargs.size(), size_t(1));
950  return makeExpr<Analyzer::GeoOperator>(
951  rex_function->getType(),
952  rex_function->getName(),
953  std::vector<std::shared_ptr<Analyzer::Expr>>{geoargs.front()});
954  } else if (rex_function->getName() == "ST_NPoints"sv) {
955  SQLTypeInfo arg_ti;
956  auto geoargs = translateGeoFunctionArg(rex_function->getOperand(0),
957  arg_ti,
958  lindex,
959  /*with_bounds=*/false,
960  /*with_render_group=*/false,
961  /*expand_geo_col=*/true,
962  /*is_projection=*/false,
963  /*use_geo_expressions=*/true);
964  CHECK_EQ(geoargs.size(), size_t(1));
965  return makeExpr<Analyzer::GeoOperator>(
966  rex_function->getType(),
967  rex_function->getName(),
968  std::vector<std::shared_ptr<Analyzer::Expr>>{geoargs.front()});
969  } else if (func_resolve(rex_function->getName(), "ST_Perimeter"sv, "ST_Area"sv)) {
970  SQLTypeInfo arg_ti;
971  auto geoargs = translateGeoFunctionArg(rex_function->getOperand(0),
972  arg_ti,
973  lindex,
974  /*with_bounds=*/false,
975  /*with_render_group=*/false,
976  /*expand_geo_col=*/true,
977  /*is_projection=*/false,
978  /*use_geo_expressions=*/true);
979  CHECK_EQ(geoargs.size(), size_t(1));
980  arg_ti = geoargs.front()->get_type_info();
981  if (arg_ti.get_type() != kPOLYGON && arg_ti.get_type() != kMULTIPOLYGON) {
982  throw QueryNotSupported(rex_function->getName() +
983  " expects a POLYGON or MULTIPOLYGON");
984  }
985 
986  return makeExpr<Analyzer::GeoFunctionOperator>(
987  rex_function->getType(),
988  rex_function->getName(),
989  std::vector<std::shared_ptr<Analyzer::Expr>>{geoargs.front()});
990  }
991 
992  // Accessors for poly bounds and render group for in-situ poly render queries
993  if (func_resolve(rex_function->getName(),
994  "MapD_GeoPolyBoundsPtr"sv /* deprecated */,
995  "OmniSci_Geo_PolyBoundsPtr"sv)) {
996  SQLTypeInfo arg_ti;
997  // get geo column plus bounds only (not expanded)
998  auto geoargs = translateGeoFunctionArg(
999  rex_function->getOperand(0), arg_ti, lindex, true, false, false);
1000  // this function only works on polys
1001  if (!IS_GEO_POLY(arg_ti.get_type())) {
1002  throw QueryNotSupported(rex_function->getName() +
1003  " expects a POLYGON or MULTIPOLYGON");
1004  }
1005  // only need the bounds argument (last), discard the rest
1006  geoargs.erase(geoargs.begin(), geoargs.end() - 1);
1007  // done
1008  return makeExpr<Analyzer::FunctionOper>(
1009  rex_function->getType(), specialized_geofunc, geoargs);
1010  } else if (func_resolve(rex_function->getName(),
1011  "MapD_GeoPolyRenderGroup"sv /* deprecated */,
1012  "OmniSci_Geo_PolyRenderGroup"sv)) {
1013  SQLTypeInfo arg_ti;
1014  // get geo column plus render_group only (not expanded)
1015  auto geoargs = translateGeoFunctionArg(
1016  rex_function->getOperand(0), arg_ti, lindex, false, true, false);
1017  // this function only works on polys
1018  if (!IS_GEO_POLY(arg_ti.get_type())) {
1019  throw QueryNotSupported(rex_function->getName() +
1020  " expects a POLYGON or MULTIPOLYGON");
1021  }
1022  // only need the render_group argument (last), discard the rest
1023  geoargs.erase(geoargs.begin(), geoargs.end() - 1);
1024  // done
1025  return makeExpr<Analyzer::FunctionOper>(
1026  rex_function->getType(), specialized_geofunc, geoargs);
1027  }
1028 
1029  // All functions below use geo col as reference and expand it as necessary
1030  SQLTypeInfo arg_ti;
1031  bool with_bounds = true;
1032  auto geoargs = translateGeoFunctionArg(
1033  rex_function->getOperand(0), arg_ti, lindex, with_bounds, false, false);
1034 
1035  if (rex_function->getName() == "ST_SRID"sv) {
1036  Datum output_srid;
1037  output_srid.intval = arg_ti.get_output_srid();
1038  return makeExpr<Analyzer::Constant>(kINT, false, output_srid);
1039  }
1040 
1041  if (func_resolve(
1042  rex_function->getName(), "ST_XMin"sv, "ST_YMin"sv, "ST_XMax"sv, "ST_YMax"sv)) {
1043  // If type has bounds - use them, otherwise look at coords
1044  if (arg_ti.has_bounds()) {
1045  if (lindex != 0) {
1046  throw QueryNotSupported(rex_function->getName() +
1047  " doesn't support indexed LINESTRINGs");
1048  }
1049  // Only need the bounds argument, discard the rest
1050  geoargs.erase(geoargs.begin(), geoargs.end() - 1);
1051 
1052  // Supply srids too - transformed geo would have a transformed bounding box
1053  Datum input_srid;
1054  input_srid.intval = arg_ti.get_input_srid();
1055  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
1056  Datum output_srid;
1057  output_srid.intval = arg_ti.get_output_srid();
1058  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
1059 
1060  specialized_geofunc += "_Bounds"s;
1061  return makeExpr<Analyzer::FunctionOper>(
1062  rex_function->getType(), specialized_geofunc, geoargs);
1063  }
1064  }
1065 
1066  // All geo function calls translated below only need the coords, extras e.g.
1067  // ring_sizes are dropped. Specialize for other/new functions if needed.
1068  geoargs.erase(geoargs.begin() + 1, geoargs.end());
1069 
1070  if (func_resolve(rex_function->getName(), "ST_X"sv, "ST_Y"sv)) {
1071  int32_t lineindex_new = 0;
1072  auto new_geoargs = translateGeoFunctionArg(
1073  rex_function->getOperand(0),
1074  arg_ti,
1075  /*lindex=*/lineindex_new, // TODO: don't care about the line index we
1076  // already translated above
1077  /*with_bounds=*/false,
1078  /*with_render_group=*/false,
1079  /*expand_geo_col=*/true,
1080  /*is_projection=*/false,
1081  /*use_geo_expressions=*/true);
1082  if (arg_ti.get_type() != kPOINT) {
1083  throw QueryNotSupported(rex_function->getName() + " expects a POINT");
1084  }
1085  CHECK_EQ(new_geoargs.size(), size_t(1));
1086  auto function_ti = rex_function->getType();
1087  if (std::dynamic_pointer_cast<Analyzer::GeoOperator>(new_geoargs.front())) {
1088  function_ti.set_notnull(false);
1089  }
1090  if (std::dynamic_pointer_cast<Analyzer::GeoConstant>(new_geoargs.front())) {
1091  // TODO(adb): fixup null handling
1092  function_ti.set_notnull(true);
1093  }
1094  return makeExpr<Analyzer::GeoOperator>(
1095  function_ti,
1096  rex_function->getName(),
1097  std::vector<std::shared_ptr<Analyzer::Expr>>{new_geoargs.front()});
1098  } else if (rex_function->getName() == "ST_Length"sv) {
1099  if (arg_ti.get_type() != kLINESTRING || lindex != 0) {
1100  throw QueryNotSupported(rex_function->getName() + " expects unindexed LINESTRING");
1101  }
1102  specialized_geofunc += suffix(arg_ti.get_type());
1103  if (arg_ti.get_subtype() == kGEOGRAPHY && arg_ti.get_output_srid() == 4326) {
1104  specialized_geofunc += "_Geodesic"s;
1105  }
1106  }
1107 
1108  // Add input compression mode and SRID args to enable on-the-fly
1109  // decompression/transforms
1110  Datum input_compression;
1111  input_compression.intval = Geospatial::get_compression_scheme(arg_ti);
1112  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
1113  Datum input_srid;
1114  input_srid.intval = arg_ti.get_input_srid();
1115  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
1116 
1117  // Add output SRID arg to enable on-the-fly transforms
1118  Datum output_srid;
1119  output_srid.intval = arg_ti.get_output_srid();
1120  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
1121 
1122  return makeExpr<Analyzer::FunctionOper>(
1123  rex_function->getType(), specialized_geofunc, geoargs);
1124 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:315
#define CHECK_EQ(x, y)
Definition: Logger.h:214
auto func_resolve
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
bool has_bounds() const
Definition: sqltypes.h:383
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:318
void set_notnull(bool n)
Definition: sqltypes.h:411
std::vector< std::shared_ptr< Analyzer::Expr > > translateGeoFunctionArg(const RexScalar *rex_scalar, SQLTypeInfo &arg_ti, int32_t &lindex, const bool with_bounds, const bool with_render_group, const bool expand_geo_col, const bool is_projection=false, const bool use_geo_expressions=false, const bool try_to_compress=false) const
Definition: sqltypes.h:44
const std::string & getName() const
std::string suffix(SQLTypes type)
Definition: GeoIR.cpp:156
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:320
#define IS_GEO_POLY(T)
Definition: sqltypes.h:249

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateUnlikely ( const RexFunctionOperator rex_function) const
private

Definition at line 973 of file RelAlgTranslator.cpp.

References CHECK, RexOperator::getOperand(), RexOperator::size(), and translateScalarRex().

Referenced by translateFunction().

974  {
975  CHECK(rex_function->size() == 1);
976  const auto arg = translateScalarRex(rex_function->getOperand(0));
977  return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.0625);
978 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
#define CHECK(condition)
Definition: Logger.h:206

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateUoper ( const RexOperator rex_operator) const
private

Definition at line 424 of file RelAlgTranslator.cpp.

References CHECK, CHECK_EQ, CHECK_NE, RexOperator::getOperand(), RexOperator::getOperator(), RexOperator::getType(), is_null(), kBOOLEAN, kCAST, kDATE, kISNOTNULL, kISNULL, kMINUS, kNOT, kNULLT, kUMINUS, kUNNEST, RexOperator::size(), and translateScalarRex().

Referenced by translateOper().

425  {
426  CHECK_EQ(size_t(1), rex_operator->size());
427  const auto operand_expr =