OmniSciDB  0fdbebe030
 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, 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, QueryFeatureDescriptor &feature_stash)
 
std::shared_ptr< Analyzer::ExprtranslateScalarRex (const RexScalar *rex) const
 

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::ExprtranslateLower (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateCardinality (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateItem (const RexFunctionOperator *) const
 
std::shared_ptr< Analyzer::ExprtranslateNow () 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::ExprtranslateGeoConstructor (const RexFunctionOperator *) 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
 
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_
 
const Executorexecutor_
 
const std::unordered_map
< const RelAlgNode *, int > 
input_to_nest_level_
 
const std::vector< JoinTypejoin_types_
 
time_t now_
 
const bool just_explain_
 
QueryFeatureDescriptorfeature_stash_
 

Detailed Description

Definition at line 41 of file RelAlgTranslator.h.

Constructor & Destructor Documentation

RelAlgTranslator::RelAlgTranslator ( const Catalog_Namespace::Catalog cat,
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,
QueryFeatureDescriptor feature_stash 
)
inline

Definition at line 43 of file RelAlgTranslator.h.

50  : cat_(cat)
51  , executor_(executor)
52  , input_to_nest_level_(input_to_nest_level)
53  , join_types_(join_types)
54  , now_(now)
55  , just_explain_(just_explain)
56  , feature_stash_(feature_stash) {}
const std::vector< JoinType > join_types_
const Executor * executor_
QueryFeatureDescriptor & feature_stash_
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
const bool just_explain_
const Catalog_Namespace::Catalog & cat_

Member Function Documentation

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::getInIntegerSetExpr ( std::shared_ptr< Analyzer::Expr arg,
const ResultSet val_set 
) const
private

Definition at line 735 of file RelAlgTranslator.cpp.

References 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(), inline_int_null_val(), kENCODING_DICT, and Asio::start().

Referenced by translateInOper().

737  {
738  if (!can_use_parallel_algorithms(val_set)) {
739  return nullptr;
740  }
741  std::vector<int64_t> value_exprs;
742  const size_t fetcher_count = cpu_threads();
743  std::vector<std::vector<int64_t>> expr_set(fetcher_count);
744  std::vector<std::future<void>> fetcher_threads;
745  const auto& arg_type = arg->get_type_info();
746  const auto entry_count = val_set.entryCount();
747  CHECK_EQ(size_t(1), val_set.colCount());
748  const auto& col_type = val_set.getColType(0);
749  if (g_cluster && arg_type.is_string() &&
750  (col_type.get_comp_param() <= 0 || arg_type.get_comp_param() <= 0)) {
751  // Skip this case for now, see comment for fill_dictionary_encoded_in_vals.
752  return nullptr;
753  }
754  std::atomic<size_t> total_in_vals_count{0};
755  for (size_t i = 0,
756  start_entry = 0,
757  stride = (entry_count + fetcher_count - 1) / fetcher_count;
758  i < fetcher_count && start_entry < entry_count;
759  ++i, start_entry += stride) {
760  expr_set[i].reserve(entry_count / fetcher_count);
761  const auto end_entry = std::min(start_entry + stride, entry_count);
762  if (arg_type.is_string()) {
763  CHECK_EQ(kENCODING_DICT, arg_type.get_compression());
764  // const int32_t dest_dict_id = arg_type.get_comp_param();
765  // const int32_t source_dict_id = col_type.get_comp_param();
766  const DictRef dest_dict_ref(arg_type.get_comp_param(), cat_.getDatabaseId());
767  const DictRef source_dict_ref(col_type.get_comp_param(), cat_.getDatabaseId());
768  const auto dd = executor_->getStringDictionaryProxy(
769  arg_type.get_comp_param(), val_set.getRowSetMemOwner(), true);
770  const auto sd = executor_->getStringDictionaryProxy(
771  col_type.get_comp_param(), val_set.getRowSetMemOwner(), true);
772  CHECK(sd);
773  const auto needle_null_val = inline_int_null_val(arg_type);
774  fetcher_threads.push_back(std::async(
775  std::launch::async,
776  [this,
777  &val_set,
778  &total_in_vals_count,
779  sd,
780  dd,
781  source_dict_ref,
782  dest_dict_ref,
783  needle_null_val](
784  std::vector<int64_t>& in_vals, const size_t start, const size_t end) {
785  if (g_cluster) {
786  CHECK_GE(dd->getGeneration(), 0);
788  total_in_vals_count,
789  &val_set,
790  {start, end},
792  source_dict_ref,
793  dest_dict_ref,
794  dd->getGeneration(),
795  needle_null_val);
796  } else {
798  total_in_vals_count,
799  &val_set,
800  {start, end},
801  sd,
802  dd,
803  needle_null_val);
804  }
805  },
806  std::ref(expr_set[i]),
807  start_entry,
808  end_entry));
809  } else {
810  CHECK(arg_type.is_integer());
811  fetcher_threads.push_back(std::async(
812  std::launch::async,
813  [&val_set, &total_in_vals_count](
814  std::vector<int64_t>& in_vals, const size_t start, const size_t end) {
815  fill_integer_in_vals(in_vals, total_in_vals_count, &val_set, {start, end});
816  },
817  std::ref(expr_set[i]),
818  start_entry,
819  end_entry));
820  }
821  }
822  for (auto& child : fetcher_threads) {
823  child.get();
824  }
825 
826  val_set.moveToBegin();
827  value_exprs.reserve(entry_count);
828  for (auto& exprs : expr_set) {
829  value_exprs.insert(value_exprs.end(), exprs.begin(), exprs.end());
830  }
831  return makeExpr<Analyzer::InIntegerSet>(
832  arg, value_exprs, arg_type.get_notnull() && col_type.get_notnull());
833 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const Executor * executor_
#define CHECK_GE(x, y)
Definition: Logger.h:210
void start()
Definition: Asio.cpp:33
CHECK(cgen_state)
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:210
const std::vector< LeafHostInfo > & getStringDictionaryHosts() const
Definition: Catalog.cpp:1480
bool can_use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:895
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool g_cluster
int cpu_threads()
Definition: thread_count.h:25
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 1278 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().

1279  {
1280  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1281  expr_list;
1282  CHECK_EQ(size_t(1), rex_function->size());
1283  const auto operand = translateScalarRex(rex_function->getOperand(0));
1284  const auto& operand_ti = operand->get_type_info();
1285  CHECK(operand_ti.is_number());
1286  const auto zero = makeNumericConstant(operand_ti, 0);
1287  const auto lt_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kLT, kONE, operand, zero);
1288  const auto uminus_operand =
1289  makeExpr<Analyzer::UOper>(operand_ti.get_type(), kUMINUS, operand);
1290  expr_list.emplace_back(lt_zero, uminus_operand);
1291  return makeExpr<Analyzer::CaseExpr>(operand_ti, false, expr_list, operand);
1292 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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)
CHECK(cgen_state)
Definition: sqldefs.h:69
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 216 of file RelAlgTranslator.cpp.

References CHECK_LE, CHECK_LT, 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, kINT, RexAgg::size(), and ThriftSerializers::takes_arg().

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

218  {
219  const auto agg_kind = rex->getKind();
220  const bool is_distinct = rex->isDistinct();
221  const bool takes_arg{rex->size() > 0};
222  std::shared_ptr<Analyzer::Expr> arg_expr;
223  std::shared_ptr<Analyzer::Constant> err_rate;
224  if (takes_arg) {
225  const auto operand = rex->getOperand(0);
226  CHECK_LT(operand, scalar_sources.size());
227  CHECK_LE(rex->size(), 2u);
228  arg_expr = scalar_sources[operand];
229  if (agg_kind == kAPPROX_COUNT_DISTINCT && rex->size() == 2) {
230  err_rate = std::dynamic_pointer_cast<Analyzer::Constant>(
231  scalar_sources[rex->getOperand(1)]);
232  if (!err_rate || err_rate->get_type_info().get_type() != kINT ||
233  err_rate->get_constval().intval < 1 || err_rate->get_constval().intval > 100) {
234  throw std::runtime_error(
235  "APPROX_COUNT_DISTINCT's second parameter should be SMALLINT literal between "
236  "1 and 100");
237  }
238  }
239  const auto& arg_ti = arg_expr->get_type_info();
240  if (!is_agg_supported_for_type(agg_kind, arg_ti)) {
241  throw std::runtime_error("Aggregate on " + arg_ti.get_type_name() +
242  " is not supported yet.");
243  }
244  }
245  const auto agg_ti = get_agg_type(agg_kind, arg_expr.get());
246  return makeExpr<Analyzer::AggExpr>(agg_ti, agg_kind, arg_expr, is_distinct, err_rate);
247 }
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:207
#define CHECK_LE(x, y)
Definition: Logger.h:208
bool takes_arg(const TargetInfo &target_info)
bool isDistinct() const
size_t size() const
Definition: sqltypes.h:46
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 1320 of file RelAlgTranslator.cpp.

References CHECK(), feature_stash_, 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().

1321  {
1322  if (rex_function->getType().get_subtype() == kNULLT) {
1323  auto sql_type = rex_function->getType();
1324  CHECK(sql_type.get_type() == kARRAY);
1325 
1326  // FIX-ME: Deal with NULL arrays
1327  auto translated_function_args(translateFunctionArgs(rex_function));
1328  if (translated_function_args.size() > 0) {
1329  const auto first_element_logical_type =
1330  get_nullable_logical_type_info(translated_function_args[0]->get_type_info());
1331 
1332  auto diff_elem_itr =
1333  std::find_if(translated_function_args.begin(),
1334  translated_function_args.end(),
1335  [first_element_logical_type](const auto expr) {
1336  return first_element_logical_type !=
1337  get_nullable_logical_type_info(expr->get_type_info());
1338  });
1339  if (diff_elem_itr != translated_function_args.end()) {
1340  throw std::runtime_error(
1341  "Element " +
1342  std::to_string(diff_elem_itr - translated_function_args.begin()) +
1343  " is not of the same type as other elements of the array. Consider casting "
1344  "to force this condition.\nElement Type: " +
1345  get_nullable_logical_type_info((*diff_elem_itr)->get_type_info())
1346  .to_string() +
1347  "\nArray type: " + first_element_logical_type.to_string());
1348  }
1349 
1350  if (first_element_logical_type.is_string() &&
1351  !first_element_logical_type.is_dict_encoded_string()) {
1352  sql_type.set_subtype(first_element_logical_type.get_type());
1353  sql_type.set_compression(kENCODING_FIXED);
1354  } else if (first_element_logical_type.is_dict_encoded_string()) {
1355  sql_type.set_subtype(first_element_logical_type.get_type());
1356  sql_type.set_comp_param(TRANSIENT_DICT_ID);
1357  } else {
1358  sql_type.set_subtype(first_element_logical_type.get_type());
1359  sql_type.set_scale(first_element_logical_type.get_scale());
1360  sql_type.set_precision(first_element_logical_type.get_precision());
1361  }
1362 
1363  feature_stash_.setCPUOnlyExecutionRequired();
1364  return makeExpr<Analyzer::ArrayExpr>(
1365  sql_type, translated_function_args, feature_stash_.getAndBumpArrayExprCount());
1366  } else {
1367  // defaulting to valid sub-type for convenience
1368  sql_type.set_subtype(kBOOLEAN);
1369  return makeExpr<Analyzer::ArrayExpr>(
1370  sql_type, translated_function_args, feature_stash_.getAndBumpArrayExprCount());
1371  }
1372  } else {
1373  feature_stash_.setCPUOnlyExecutionRequired();
1374  return makeExpr<Analyzer::ArrayExpr>(rex_function->getType(),
1375  translateFunctionArgs(rex_function),
1376  feature_stash_.getAndBumpArrayExprCount());
1377  }
1378 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:249
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:811
const SQLTypeInfo & getType() const
std::string to_string(char const *&&v)
QueryFeatureDescriptor & feature_stash_
CHECK(cgen_state)
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
#define TRANSIENT_DICT_ID
Definition: sqltypes.h:187

+ 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 757 of file RelAlgTranslatorGeo.cpp.

References CHECK_EQ, func_resolve, SQLTypeInfo::get_comp_param(), SQLTypeInfo::get_compression(), 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{RelAlgTranslatorGeo.cpp}::suffix(), and translateGeoFunctionArg().

Referenced by translateFunction(), and translateTernaryGeoFunction().

758  {
759  auto function_name = rex_function->getName();
760  auto return_type = rex_function->getType();
761  bool swap_args = false;
762  bool with_bounds = false;
763  bool negate_result = false;
764  if (function_name == "ST_DWithin"sv) {
765  CHECK_EQ(size_t(3), rex_function->size());
766  function_name = "ST_Distance";
767  return_type = SQLTypeInfo(kDOUBLE, false);
768  } else if (function_name == "ST_DFullyWithin"sv) {
769  CHECK_EQ(size_t(3), rex_function->size());
770  function_name = "ST_MaxDistance";
771  return_type = SQLTypeInfo(kDOUBLE, false);
772  } else {
773  CHECK_EQ(size_t(2), rex_function->size());
774  }
775  if (function_name == "ST_Within"sv) {
776  function_name = "ST_Contains";
777  swap_args = true;
778  } else if (function_name == "ST_Disjoint"sv) {
779  function_name = "ST_Intersects";
780  negate_result = true;
781  }
782  if (func_resolve(function_name, "ST_Contains"sv, "ST_Intersects"sv)) {
783  with_bounds = true;
784  }
785 
786  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
787  SQLTypeInfo arg0_ti;
788  SQLTypeInfo arg1_ti;
789  int32_t lindex0 = 0;
790  int32_t lindex1 = 0;
791 
792  auto geoargs0 = translateGeoFunctionArg(rex_function->getOperand(swap_args ? 1 : 0),
793  arg0_ti,
794  lindex0,
795  with_bounds,
796  false,
797  false);
798  if (arg0_ti.get_type() == kLINESTRING) {
799  Datum index;
800  index.intval = lindex0;
801  geoargs0.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
802  }
803  geoargs.insert(geoargs.end(), geoargs0.begin(), geoargs0.end());
804  auto geoargs1 = translateGeoFunctionArg(rex_function->getOperand(swap_args ? 0 : 1),
805  arg1_ti,
806  lindex1,
807  with_bounds,
808  false,
809  false);
810  if (arg1_ti.get_type() == kLINESTRING) {
811  Datum index;
812  index.intval = lindex1;
813  geoargs1.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
814  }
815  geoargs.insert(geoargs.end(), geoargs1.begin(), geoargs1.end());
816 
817  if (arg0_ti.get_subtype() != kNULLT && arg0_ti.get_subtype() != arg1_ti.get_subtype()) {
818  throw QueryNotSupported(rex_function->getName() +
819  " accepts either two GEOGRAPHY or two GEOMETRY arguments");
820  }
821  // Check SRID match if at least one is set/valid
822  if ((arg0_ti.get_output_srid() > 0 || arg1_ti.get_output_srid() > 0) &&
823  arg0_ti.get_output_srid() != arg1_ti.get_output_srid()) {
824  throw QueryNotSupported(rex_function->getName() + " cannot accept different SRIDs");
825  }
826 
827  std::string specialized_geofunc{function_name + suffix(arg0_ti.get_type()) +
828  suffix(arg1_ti.get_type())};
829 
830  if (arg0_ti.get_subtype() == kGEOGRAPHY && arg0_ti.get_output_srid() == 4326) {
831  // Need to call geodesic runtime functions
832  if (function_name == "ST_Distance"sv) {
833  if ((arg0_ti.get_type() == kPOINT ||
834  (arg0_ti.get_type() == kLINESTRING && lindex0 != 0)) &&
835  (arg1_ti.get_type() == kPOINT ||
836  (arg1_ti.get_type() == kLINESTRING && lindex1 != 0))) {
837  // Geodesic distance between points (or indexed linestrings)
838  specialized_geofunc += "_Geodesic"s;
839  } else {
840  throw QueryNotSupported(function_name +
841  " currently doesn't accept non-POINT geographies");
842  }
843  } else if (rex_function->getName() == "ST_Contains"sv) {
844  // We currently don't have a geodesic implementation of ST_Contains,
845  // allowing calls to a [less precise] cartesian implementation.
846  } else {
847  throw QueryNotSupported(function_name + " doesn't accept geographies");
848  }
849  } else if (function_name == "ST_Distance"sv && rex_function->size() == 3) {
850  if (arg0_ti.get_type() == kPOINT && arg1_ti.get_type() == kPOINT) {
851  // Cartesian distance between points used by ST_DWithin - switch to faster Squared
852  specialized_geofunc += "_Squared"s;
853  }
854  }
855 
856  // Add first input's compression mode and SRID args to enable on-the-fly
857  // decompression/transforms
858  Datum input_compression0;
859  input_compression0.intval =
860  (arg0_ti.get_compression() == kENCODING_GEOINT && arg0_ti.get_comp_param() == 32)
861  ? 1
862  : 0;
863  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression0));
864  Datum input_srid0;
865  input_srid0.intval = arg0_ti.get_input_srid();
866  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid0));
867 
868  // Add second input's compression mode and SRID args to enable on-the-fly
869  // decompression/transforms
870  Datum input_compression1;
871  input_compression1.intval =
872  (arg1_ti.get_compression() == kENCODING_GEOINT && arg1_ti.get_comp_param() == 32)
873  ? 1
874  : 0;
875  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression1));
876  Datum input_srid1;
877  input_srid1.intval = arg1_ti.get_input_srid();
878  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid1));
879 
880  // Add output SRID arg to enable on-the-fly transforms
881  Datum output_srid;
882  output_srid.intval = arg0_ti.get_output_srid();
883  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
884 
885  auto result =
886  makeExpr<Analyzer::FunctionOper>(return_type, specialized_geofunc, geoargs);
887  if (negate_result) {
888  return makeExpr<Analyzer::UOper>(kBOOLEAN, kNOT, result);
889  }
890  return result;
891 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:249
#define CHECK_EQ(x, y)
Definition: Logger.h:205
auto func_resolve
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:248
int32_t intval
Definition: sqltypes.h:126
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:256
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:257
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:252
Definition: sqltypes.h:46
const std::string & getName() const
Definition: sqldefs.h:39
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
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:254

+ 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 1222 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1223  {
1224  const auto ret_ti = rex_function->getType();
1225  const auto arg = translateScalarRex(rex_function->getOperand(0));
1226  const auto arg_ti = arg->get_type_info();
1227  if (!arg_ti.is_array()) {
1228  throw std::runtime_error(rex_function->getName() + " expects an array expression.");
1229  }
1230  if (arg_ti.get_subtype() == kARRAY) {
1231  throw std::runtime_error(rex_function->getName() +
1232  " expects one-dimension array expression.");
1233  }
1234  const auto array_size = arg_ti.get_size();
1235  const auto array_elem_size = arg_ti.get_elem_type().get_array_context_logical_size();
1236 
1237  if (array_size > 0) {
1238  if (array_elem_size <= 0) {
1239  throw std::runtime_error(rex_function->getName() +
1240  ": unexpected array element type.");
1241  }
1242  // Return cardinality of a fixed length array
1243  return makeNumericConstant(ret_ti, array_size / array_elem_size);
1244  }
1245  // Variable length array cardinality will be calculated at runtime
1246  return makeExpr<Analyzer::CardinalityExpr>(arg);
1247 }
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 889 of file RelAlgTranslator.cpp.

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

Referenced by translateScalarRex().

890  {
891  std::shared_ptr<Analyzer::Expr> else_expr;
892  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
893  expr_list;
894  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
895  const auto when_expr = translateScalarRex(rex_case->getWhen(i));
896  const auto then_expr = translateScalarRex(rex_case->getThen(i));
897  expr_list.emplace_back(when_expr, then_expr);
898  }
899  if (rex_case->getElse()) {
900  else_expr = translateScalarRex(rex_case->getElse());
901  }
902  return Parser::CaseExpr::normalize(expr_list, else_expr);
903 }
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:903
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::translateDateadd ( const RexFunctionOperator rex_function) const
private

Definition at line 1018 of file RelAlgTranslator.cpp.

References CHECK_EQ, field(), fold_expr(), DateTimeUtils::get_dateadd_high_precision_adjusted_scale(), DateTimeUtils::get_dateadd_timestamp_precision_scale(), RexOperator::getOperand(), DateTimeUtils::is_subsecond_dateadd_field(), kBIGINT, kDIVIDE, kONE, kTIME, kTIMESTAMP, anonymous_namespace{RelAlgTranslator.cpp}::makeNumericConstant(), RexOperator::size(), to_dateadd_field(), translateScalarRex(), and anonymous_namespace{RelAlgTranslator.cpp}::validate_datetime_datepart_argument().

Referenced by translateFunction().

1019  {
1020  CHECK_EQ(size_t(3), rex_function->size());
1021  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
1022  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
1024  const auto number_units = translateScalarRex(rex_function->getOperand(1));
1025  const auto number_units_const =
1026  std::dynamic_pointer_cast<Analyzer::Constant>(number_units);
1027  if (number_units_const && number_units_const->get_is_null()) {
1028  throw std::runtime_error("The 'Interval' argument literal must not be 'null'.");
1029  }
1030  auto cast_number_units = number_units->add_cast(SQLTypeInfo(kBIGINT, false));
1031  const auto datetime = translateScalarRex(rex_function->getOperand(2));
1032  const auto& datetime_ti = datetime->get_type_info();
1033  if (datetime_ti.get_type() == kTIME) {
1034  throw std::runtime_error("DateAdd operation not supported for TIME.");
1035  }
1036  const auto& field = to_dateadd_field(*timeunit_lit->get_constval().stringval);
1037  if (!datetime_ti.is_high_precision_timestamp() &&
1039  // Scale the number to get value in seconds
1040  const auto bigint_ti = SQLTypeInfo(kBIGINT, false);
1041  cast_number_units = makeExpr<Analyzer::BinOper>(
1042  bigint_ti.get_type(),
1043  kDIVIDE,
1044  kONE,
1045  cast_number_units,
1046  makeNumericConstant(bigint_ti,
1048  cast_number_units = fold_expr(cast_number_units.get());
1049  }
1050  if (datetime_ti.is_high_precision_timestamp() &&
1053  field, datetime_ti.get_dimension());
1054  if (oper_scale.first) {
1055  // scale number to desired precision
1056  const auto bigint_ti = SQLTypeInfo(kBIGINT, false);
1057  cast_number_units =
1058  makeExpr<Analyzer::BinOper>(bigint_ti.get_type(),
1059  oper_scale.first,
1060  kONE,
1061  cast_number_units,
1062  makeNumericConstant(bigint_ti, oper_scale.second));
1063  cast_number_units = fold_expr(cast_number_units.get());
1064  }
1065  }
1066  return makeExpr<Analyzer::DateaddExpr>(
1067  SQLTypeInfo(kTIMESTAMP, datetime_ti.get_dimension(), 0, false),
1068  to_dateadd_field(*timeunit_lit->get_constval().stringval),
1069  cast_number_units,
1070  datetime);
1071 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
Definition: sqltypes.h:50
constexpr int64_t get_dateadd_timestamp_precision_scale(const DateaddField field)
Definition: DateTimeUtils.h:67
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)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const std::pair< SQLOps, int64_t > get_dateadd_high_precision_adjusted_scale(const DateaddField field, int32_t dimen)
Definition: sqldefs.h:69
constexpr bool is_subsecond_dateadd_field(const DateaddField field)
Definition: DateTimeUtils.h:99
void validate_datetime_datepart_argument(const std::shared_ptr< Analyzer::Constant > literal_expr)
DateaddField to_dateadd_field(const std::string &field)
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::translateDatediff ( const RexFunctionOperator rex_function) const
private

Definition at line 1163 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1164  {
1165  CHECK_EQ(size_t(3), rex_function->size());
1166  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
1167  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
1169  const auto start = translateScalarRex(rex_function->getOperand(1));
1170  const auto end = translateScalarRex(rex_function->getOperand(2));
1171  const auto field = to_datediff_field(*timeunit_lit->get_constval().stringval);
1172  return makeExpr<Analyzer::DatediffExpr>(SQLTypeInfo(kBIGINT, false), field, start, end);
1173 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
void start()
Definition: Asio.cpp:33
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 1175 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().

1176  {
1177  CHECK_EQ(size_t(2), rex_function->size());
1178  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
1179  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
1181  const auto from_expr = translateScalarRex(rex_function->getOperand(1));
1182  return ExtractExpr::generate(
1183  from_expr, to_datepart_field(*timeunit_lit->get_constval().stringval));
1184 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 1082 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().

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

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

Referenced by translateFunction().

1263  {
1264  CHECK_EQ(size_t(1), rex_function->size());
1265  const auto arg = translateScalarRex(rex_function->getOperand(0));
1266  const auto arg_lit = std::dynamic_pointer_cast<Analyzer::Constant>(arg);
1267  const std::string datetime_err{R"(Only DATETIME('NOW') supported for now.)"};
1268  if (!arg_lit || arg_lit->get_is_null()) {
1269  throw std::runtime_error(datetime_err);
1270  }
1271  CHECK(arg_lit->get_type_info().is_string());
1272  if (*arg_lit->get_constval().stringval != "NOW"sv) {
1273  throw std::runtime_error(datetime_err);
1274  }
1275  return translateNow();
1276 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 > translateNow() const
CHECK(cgen_state)

+ 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 959 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().

960  {
961  CHECK_EQ(size_t(2), rex_function->size());
962  const auto timeunit = translateScalarRex(rex_function->getOperand(0));
963  const auto timeunit_lit = std::dynamic_pointer_cast<Analyzer::Constant>(timeunit);
965  const auto from_expr = translateScalarRex(rex_function->getOperand(1));
966  const bool is_date_trunc = rex_function->getName() == "PG_DATE_TRUNC"sv;
967  if (is_date_trunc) {
968  return DateTruncExpr::generate(from_expr, *timeunit_lit->get_constval().stringval);
969  } else {
970  return ExtractExpr::generate(from_expr, *timeunit_lit->get_constval().stringval);
971  }
972 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 1380 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, bind_function(), CHECK(), CHECK_EQ, ext_arg_type_to_type_info(), func_resolve, g_enable_experimental_string_functions, RexFunctionOperator::getName(), RexOperator::getOperand(), RexOperator::getType(), SQLTypeInfo::is_decimal(), kDIVIDE, kONE, kSMALLINT, kTEXT, Parser::OperExpr::normalize(), rewrite_to_date_trunc(), SQLTypeInfo::set_notnull(), RexOperator::size(), Datum::smallintval, translateAbs(), translateArrayFunction(), translateBinaryGeoFunction(), translateCardinality(), translateDateadd(), translateDatediff(), translateDatepart(), translateDatetime(), translateExtract(), translateFunctionArgs(), translateFunctionWithGeoArg(), translateGeoConstructor(), translateHPTLiteral(), translateItem(), translateKeyForString(), translateLength(), translateLike(), translateLikely(), translateLower(), translateNow(), translateOffsetInFragment(), translateRegexp(), translateScalarRex(), translateSign(), translateTernaryGeoFunction(), translateUnaryGeoFunction(), and translateUnlikely().

Referenced by translateScalarRex().

1381  {
1382  if (func_resolve(rex_function->getName(), "LIKE"sv, "PG_ILIKE"sv)) {
1383  return translateLike(rex_function);
1384  }
1385  if (rex_function->getName() == "REGEXP_LIKE"sv) {
1386  return translateRegexp(rex_function);
1387  }
1388  if (rex_function->getName() == "LIKELY"sv) {
1389  return translateLikely(rex_function);
1390  }
1391  if (rex_function->getName() == "UNLIKELY"sv) {
1392  return translateUnlikely(rex_function);
1393  }
1394  if (func_resolve(rex_function->getName(), "PG_EXTRACT"sv, "PG_DATE_TRUNC"sv)) {
1395  return translateExtract(rex_function);
1396  }
1397  if (rex_function->getName() == "DATEADD"sv) {
1398  return translateDateadd(rex_function);
1399  }
1400  if (rex_function->getName() == "DATEDIFF"sv) {
1401  return translateDatediff(rex_function);
1402  }
1403  if (rex_function->getName() == "DATEPART"sv) {
1404  return translateDatepart(rex_function);
1405  }
1406  if (func_resolve(rex_function->getName(), "LENGTH"sv, "CHAR_LENGTH"sv)) {
1407  return translateLength(rex_function);
1408  }
1409  if (rex_function->getName() == "KEY_FOR_STRING"sv) {
1410  return translateKeyForString(rex_function);
1411  }
1412  if (g_enable_experimental_string_functions && rex_function->getName() == "LOWER"sv) {
1413  return translateLower(rex_function);
1414  }
1415  if (func_resolve(rex_function->getName(), "CARDINALITY"sv, "ARRAY_LENGTH"sv)) {
1416  return translateCardinality(rex_function);
1417  }
1418  if (rex_function->getName() == "ITEM"sv) {
1419  return translateItem(rex_function);
1420  }
1421  if (rex_function->getName() == "NOW"sv) {
1422  return translateNow();
1423  }
1424  if (rex_function->getName() == "DATETIME"sv) {
1425  return translateDatetime(rex_function);
1426  }
1427  if (func_resolve(rex_function->getName(), "usTIMESTAMP"sv, "nsTIMESTAMP"sv)) {
1428  return translateHPTLiteral(rex_function);
1429  }
1430  if (rex_function->getName() == "ABS"sv) {
1431  return translateAbs(rex_function);
1432  }
1433  if (rex_function->getName() == "SIGN"sv) {
1434  return translateSign(rex_function);
1435  }
1436  if (func_resolve(rex_function->getName(), "CEIL"sv, "FLOOR"sv)) {
1437  return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1438  rex_function->getType(),
1439  rex_function->getName(),
1440  translateFunctionArgs(rex_function));
1441  } else if (rex_function->getName() == "ROUND"sv) {
1442  std::vector<std::shared_ptr<Analyzer::Expr>> args =
1443  translateFunctionArgs(rex_function);
1444 
1445  if (rex_function->size() == 1) {
1446  // push a 0 constant if 2nd operand is missing.
1447  // this needs to be done as calcite returns
1448  // only the 1st operand without defaulting the 2nd one
1449  // when the user did not specify the 2nd operand.
1450  SQLTypes t = kSMALLINT;
1451  Datum d;
1452  d.smallintval = 0;
1453  args.push_back(makeExpr<Analyzer::Constant>(t, false, d));
1454  }
1455 
1456  // make sure we have only 2 operands
1457  CHECK(args.size() == 2);
1458 
1459  if (!args[0]->get_type_info().is_number()) {
1460  throw std::runtime_error("Only numeric 1st operands are supported");
1461  }
1462 
1463  // the 2nd operand does not need to be a constant
1464  // it can happily reference another integer column
1465  if (!args[1]->get_type_info().is_integer()) {
1466  throw std::runtime_error("Only integer 2nd operands are supported");
1467  }
1468 
1469  // Calcite may upcast decimals in a way that is
1470  // incompatible with the extension function input. Play it safe and stick with the
1471  // argument type instead.
1472  const SQLTypeInfo ret_ti = args[0]->get_type_info().is_decimal()
1473  ? args[0]->get_type_info()
1474  : rex_function->getType();
1475 
1476  return makeExpr<Analyzer::FunctionOperWithCustomTypeHandling>(
1477  ret_ti, rex_function->getName(), args);
1478  }
1479  if (rex_function->getName() == "DATETIME_PLUS"sv) {
1480  auto dt_plus = makeExpr<Analyzer::FunctionOper>(rex_function->getType(),
1481  rex_function->getName(),
1482  translateFunctionArgs(rex_function));
1483  const auto date_trunc = rewrite_to_date_trunc(dt_plus.get());
1484  if (date_trunc) {
1485  return date_trunc;
1486  }
1487  return translateDateadd(rex_function);
1488  }
1489  if (rex_function->getName() == "/INT"sv) {
1490  CHECK_EQ(size_t(2), rex_function->size());
1491  std::shared_ptr<Analyzer::Expr> lhs = translateScalarRex(rex_function->getOperand(0));
1492  std::shared_ptr<Analyzer::Expr> rhs = translateScalarRex(rex_function->getOperand(1));
1493  const auto rhs_lit = std::dynamic_pointer_cast<Analyzer::Constant>(rhs);
1494  return Parser::OperExpr::normalize(kDIVIDE, kONE, lhs, rhs);
1495  }
1496  if (rex_function->getName() == "Reinterpret"sv) {
1497  CHECK_EQ(size_t(1), rex_function->size());
1498  return translateScalarRex(rex_function->getOperand(0));
1499  }
1500  if (func_resolve(rex_function->getName(),
1501  "ST_X"sv,
1502  "ST_Y"sv,
1503  "ST_XMin"sv,
1504  "ST_YMin"sv,
1505  "ST_XMax"sv,
1506  "ST_YMax"sv,
1507  "ST_NRings"sv,
1508  "ST_NPoints"sv,
1509  "ST_Length"sv,
1510  "ST_Perimeter"sv,
1511  "ST_Area"sv,
1512  "ST_SRID"sv,
1513  "MapD_GeoPolyBoundsPtr"sv /* deprecated */,
1514  "MapD_GeoPolyBoundsPtr"sv /* deprecated */,
1515  "OmniSci_Geo_PolyBoundsPtr"sv,
1516  "OmniSci_Geo_PolyRenderGroup"sv)) {
1517  CHECK_EQ(rex_function->size(), size_t(1));
1518  return translateUnaryGeoFunction(rex_function);
1519  }
1520  if (func_resolve(rex_function->getName(),
1521  "convert_meters_to_pixel_width"sv,
1522  "convert_meters_to_pixel_height"sv,
1523  "is_point_in_view"sv,
1524  "is_point_size_in_view"sv)) {
1525  return translateFunctionWithGeoArg(rex_function);
1526  }
1527  if (func_resolve(rex_function->getName(),
1528  "ST_Distance"sv,
1529  "ST_MaxDistance"sv,
1530  "ST_Intersects"sv,
1531  "ST_Disjoint"sv,
1532  "ST_Contains"sv,
1533  "ST_Within"sv)) {
1534  CHECK_EQ(rex_function->size(), size_t(2));
1535  return translateBinaryGeoFunction(rex_function);
1536  }
1537  if (func_resolve(rex_function->getName(), "ST_DWithin"sv, "ST_DFullyWithin"sv)) {
1538  CHECK_EQ(rex_function->size(), size_t(3));
1539  return translateTernaryGeoFunction(rex_function);
1540  }
1541  if (rex_function->getName() == "OFFSET_IN_FRAGMENT"sv) {
1542  CHECK_EQ(size_t(0), rex_function->size());
1543  return translateOffsetInFragment();
1544  }
1545  if (rex_function->getName() == "ARRAY"sv) {
1546  // Var args; currently no check. Possible fix-me -- can array have 0 elements?
1547  return translateArrayFunction(rex_function);
1548  }
1549  if (func_resolve(rex_function->getName(),
1550  "ST_GeomFromText"sv,
1551  "ST_GeogFromText"sv,
1552  "ST_Point"sv,
1553  "ST_SetSRID"sv)) {
1554  return translateGeoConstructor(rex_function);
1555  }
1556 
1557  auto arg_expr_list = translateFunctionArgs(rex_function);
1558  if (rex_function->getName() == std::string("||") ||
1559  rex_function->getName() == std::string("SUBSTRING")) {
1560  SQLTypeInfo ret_ti(kTEXT, false);
1561  return makeExpr<Analyzer::FunctionOper>(
1562  ret_ti, rex_function->getName(), arg_expr_list);
1563  }
1564  // Reset possibly wrong return type of rex_function to the return
1565  // type of the optimal valid implementation. The return type can be
1566  // wrong in the case of multiple implementations of UDF functions
1567  // that have different return types but Calcite specifies the return
1568  // type according to the first implementation.
1569  auto ext_func_sig = bind_function(rex_function->getName(), arg_expr_list);
1570  auto ret_ti = ext_arg_type_to_type_info(ext_func_sig.getRet());
1571  // By defualt, the extension function type will not allow nulls. If one of the arguments
1572  // is nullable, the extension function must also explicitly allow nulls.
1573  bool arguments_not_null = true;
1574  for (const auto& arg_expr : arg_expr_list) {
1575  if (!arg_expr->get_type_info().get_notnull()) {
1576  arguments_not_null = false;
1577  break;
1578  }
1579  }
1580  ret_ti.set_notnull(arguments_not_null);
1581  return makeExpr<Analyzer::FunctionOper>(ret_ti, rex_function->getName(), arg_expr_list);
1582 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
auto func_resolve
std::shared_ptr< Analyzer::Expr > translateOffsetInFragment() const
std::shared_ptr< Analyzer::Expr > translateRegexp(const RexFunctionOperator *) const
SQLTypes
Definition: sqltypes.h:39
std::shared_ptr< Analyzer::Expr > translateUnlikely(const RexFunctionOperator *) const
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
ExtensionFunction bind_function(std::string name, Analyzer::ExpressionPtrVector func_args, const std::vector< ExtensionFunction > &ext_funcs)
std::shared_ptr< Analyzer::Expr > translateDateadd(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateNow() const
std::shared_ptr< Analyzer::Expr > translateAbs(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateItem(const RexFunctionOperator *) 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
CHECK(cgen_state)
std::shared_ptr< Analyzer::Expr > translateDatetime(const RexFunctionOperator *) const
int16_t smallintval
Definition: sqltypes.h:125
std::shared_ptr< Analyzer::Expr > translateGeoConstructor(const RexFunctionOperator *) 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:259
Definition: sqltypes.h:53
Analyzer::ExpressionPtrVector translateFunctionArgs(const RexFunctionOperator *) const
Definition: sqldefs.h:69
std::shared_ptr< Analyzer::Expr > translateArrayFunction(const RexFunctionOperator *) const
bool g_enable_experimental_string_functions
std::shared_ptr< Analyzer::Expr > translateLike(const RexFunctionOperator *) const
std::shared_ptr< Analyzer::Expr > translateLikely(const RexFunctionOperator *) const
void set_notnull(bool n)
Definition: sqltypes.h:345
std::shared_ptr< Analyzer::Expr > translateTernaryGeoFunction(const RexFunctionOperator *) const
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 > translateCardinality(const RexFunctionOperator *) const
bool is_decimal() const
Definition: sqltypes.h:402
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 > 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 1663 of file RelAlgTranslator.cpp.

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

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

1664  {
1665  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1666  for (size_t i = 0; i < rex_function->size(); ++i) {
1667  args.push_back(translateScalarRex(rex_function->getOperand(i)));
1668  }
1669  return args;
1670 }
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 958 of file RelAlgTranslatorGeo.cpp.

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

Referenced by translateFunction().

959  {
960  int32_t lindex = 0;
961  std::string specialized_geofunc{rex_function->getName()};
962  if (func_resolve(rex_function->getName(),
963  "convert_meters_to_pixel_width"sv,
964  "convert_meters_to_pixel_height"sv)) {
965  CHECK_EQ(rex_function->size(), 6u);
966  SQLTypeInfo arg_ti;
967  std::vector<std::shared_ptr<Analyzer::Expr>> args;
968  args.push_back(translateScalarRex(rex_function->getOperand(0)));
969  auto geoargs = translateGeoFunctionArg(
970  rex_function->getOperand(1), arg_ti, lindex, false, true, false);
971  // only works on points
972  if (arg_ti.get_type() != kPOINT) {
973  throw QueryNotSupported(rex_function->getName() +
974  " expects a point for the second argument");
975  }
976 
977  args.insert(args.end(), geoargs.begin(), geoargs.begin() + 1);
978 
979  // Add compression information
980  Datum input_compression;
981  input_compression.intval =
982  (arg_ti.get_compression() == kENCODING_GEOINT && arg_ti.get_comp_param() == 32)
983  ? 1
984  : 0;
985  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
986  if (arg_ti.get_input_srid() != 4326) {
987  throw QueryNotSupported(
988  rex_function->getName() +
989  " currently only supports points of with SRID WGS84/EPSG:4326");
990  }
991  Datum input_srid;
992  input_srid.intval = arg_ti.get_input_srid();
993  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
994  Datum output_srid;
995  // Forcing web-mercator projection for now
996  // TODO(croot): check that the input-to-output conversion routines exist?
997  output_srid.intval =
998  arg_ti.get_output_srid() != 900913 ? 900913 : arg_ti.get_output_srid();
999  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
1000 
1001  args.push_back(translateScalarRex(rex_function->getOperand(2)));
1002  args.push_back(translateScalarRex(rex_function->getOperand(3)));
1003  args.push_back(translateScalarRex(rex_function->getOperand(4)));
1004  args.push_back(translateScalarRex(rex_function->getOperand(5)));
1005  return makeExpr<Analyzer::FunctionOper>(
1006  rex_function->getType(), specialized_geofunc, args);
1007  } else if (rex_function->getName() == "is_point_in_view"sv) {
1008  CHECK_EQ(rex_function->size(), 5u);
1009  SQLTypeInfo arg_ti;
1010  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1011  auto geoargs = translateGeoFunctionArg(
1012  rex_function->getOperand(0), arg_ti, lindex, false, true, false);
1013  // only works on points
1014  if (arg_ti.get_type() != kPOINT) {
1015  throw QueryNotSupported(rex_function->getName() +
1016  " expects a point for the second argument");
1017  }
1018 
1019  args.insert(args.end(), geoargs.begin(), geoargs.begin() + 1);
1020 
1021  // Add compression information
1022  Datum input_compression;
1023  input_compression.intval =
1024  (arg_ti.get_compression() == kENCODING_GEOINT && arg_ti.get_comp_param() == 32)
1025  ? 1
1026  : 0;
1027  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
1028  if (arg_ti.get_input_srid() != 4326) {
1029  throw QueryNotSupported(
1030  rex_function->getName() +
1031  " currently only supports points of with SRID WGS84/EPSG:4326");
1032  }
1033  args.push_back(translateScalarRex(rex_function->getOperand(1)));
1034  args.push_back(translateScalarRex(rex_function->getOperand(2)));
1035  args.push_back(translateScalarRex(rex_function->getOperand(3)));
1036  args.push_back(translateScalarRex(rex_function->getOperand(4)));
1037  return makeExpr<Analyzer::FunctionOper>(
1038  rex_function->getType(), specialized_geofunc, args);
1039  } else if (rex_function->getName() == "is_point_size_in_view"sv) {
1040  CHECK_EQ(rex_function->size(), 6u);
1041  SQLTypeInfo arg_ti;
1042  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1043  auto geoargs = translateGeoFunctionArg(
1044  rex_function->getOperand(0), arg_ti, lindex, false, true, false);
1045  // only works on points
1046  if (arg_ti.get_type() != kPOINT) {
1047  throw QueryNotSupported(rex_function->getName() +
1048  " expects a point for the second argument");
1049  }
1050 
1051  args.insert(args.end(), geoargs.begin(), geoargs.begin() + 1);
1052 
1053  // Add compression information
1054  Datum input_compression;
1055  input_compression.intval =
1056  (arg_ti.get_compression() == kENCODING_GEOINT && arg_ti.get_comp_param() == 32)
1057  ? 1
1058  : 0;
1059  args.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
1060  if (arg_ti.get_input_srid() != 4326) {
1061  throw QueryNotSupported(
1062  rex_function->getName() +
1063  " currently only supports points of with SRID WGS84/EPSG:4326");
1064  }
1065  args.push_back(translateScalarRex(rex_function->getOperand(1)));
1066  args.push_back(translateScalarRex(rex_function->getOperand(2)));
1067  args.push_back(translateScalarRex(rex_function->getOperand(3)));
1068  args.push_back(translateScalarRex(rex_function->getOperand(4)));
1069  args.push_back(translateScalarRex(rex_function->getOperand(5)));
1070  return makeExpr<Analyzer::FunctionOper>(
1071  rex_function->getType(), specialized_geofunc, args);
1072  }
1073  CHECK(false);
1074  return nullptr;
1075 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 intval
Definition: sqltypes.h:126
CHECK(cgen_state)
Definition: sqltypes.h:46
const std::string & getName() 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

+ 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(), input_to_nest_level_, IS_GEO, and SPIMAP_GEO_PHYSICAL_INPUT.

Referenced by 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 
62  CHECK(!in_metainfo.empty());
63  CHECK_GE(rte_idx, 0);
64  column_id = rex_input->getIndex();
65  CHECK_LT(static_cast<size_t>(column_id), in_metainfo.size());
66  ti = in_metainfo[column_id].get_type_info();
67  }
68  CHECK(IS_GEO(ti.get_type()));
69 
70  // Return geo column reference. The geo column may be expanded if required for extension
71  // function arguments. Otherwise, the geo column reference will be translated into
72  // physical columns as required. Bounds column will be added if present and requested.
73  if (expand_geo_col) {
74  for (auto i = 0; i < ti.get_physical_coord_cols(); i++) {
75  const auto pcd = cat_.getMetadataForColumnBySpi(
76  table_id, SPIMAP_GEO_PHYSICAL_INPUT(rex_input->getIndex(), i + 1));
77  auto pcol_ti = pcd->columnType;
78  args.push_back(std::make_shared<Analyzer::ColumnVar>(
79  pcol_ti, table_id, pcd->columnId, rte_idx));
80  }
81  } else {
82  args.push_back(
83  std::make_shared<Analyzer::ColumnVar>(ti, table_id, column_id, rte_idx));
84  }
85  if (with_bounds && ti.has_bounds()) {
86  const auto bounds_cd = cat_.getMetadataForColumnBySpi(
87  table_id,
89  ti.get_physical_coord_cols() + 1));
90  auto bounds_ti = bounds_cd->columnType;
91  args.push_back(std::make_shared<Analyzer::ColumnVar>(
92  bounds_ti, table_id, bounds_cd->columnId, rte_idx));
93  }
94  if (with_render_group && ti.has_render_group()) {
95  const auto render_group_cd = cat_.getMetadataForColumnBySpi(
96  table_id,
98  ti.get_physical_coord_cols() + 2));
99  auto render_group_ti = render_group_cd->columnType;
100  args.push_back(std::make_shared<Analyzer::ColumnVar>(
101  render_group_ti, table_id, render_group_cd->columnId, rte_idx));
102  }
103  return args;
104 }
#define SPIMAP_GEO_PHYSICAL_INPUT(c, i)
Definition: Catalog.h:75
#define CHECK_GE(x, y)
Definition: Logger.h:210
unsigned getIndex() const
CHECK(cgen_state)
const ColumnDescriptor * getMetadataForColumnBySpi(const int tableId, const size_t spi) const
Definition: Catalog.cpp:1531
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
#define CHECK_LT(x, y)
Definition: Logger.h:207
const RelAlgNode * getSourceNode() const
SQLTypeInfo columnType
#define IS_GEO(T)
Definition: sqltypes.h:163
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 925 of file RelAlgTranslatorGeo.cpp.

References fold_expr(), RexOperator::getOperand(), RexOperator::getOperator(), kBOOLEAN, kDOUBLE, kMULTIPLY, kONE, RexOperator::size(), and translateScalarRex().

Referenced by translateOper().

926  {
927  if (rex_operator->size() != size_t(2)) {
928  return nullptr;
929  }
930 
931  auto geo_distance_expr = translateScalarRex(rex_operator->getOperand(0));
932  auto func_oper = dynamic_cast<Analyzer::FunctionOper*>(geo_distance_expr.get());
933  if (func_oper && func_oper->getName() == "ST_Distance_Point_Point"sv) {
934  const auto& distance_ti = SQLTypeInfo(kDOUBLE, false);
935  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
936  for (size_t i = 0; i < func_oper->getArity(); i++) {
937  geoargs.push_back(func_oper->getOwnArg(i));
938  }
939  geo_distance_expr = makeExpr<Analyzer::FunctionOper>(
940  distance_ti, "ST_Distance_Point_Point_Squared"s, geoargs);
941  auto distance_expr = translateScalarRex(rex_operator->getOperand(1));
942  if (distance_expr->get_type_info().get_type() != kDOUBLE) {
943  distance_expr->add_cast(distance_ti);
944  }
945  distance_expr = makeExpr<Analyzer::BinOper>(distance_ti,
946  distance_expr->get_contains_agg(),
947  kMULTIPLY,
948  kONE,
949  distance_expr,
950  distance_expr);
951  distance_expr = fold_expr(distance_expr.get());
952  return makeExpr<Analyzer::BinOper>(
953  kBOOLEAN, rex_operator->getOperator(), kONE, geo_distance_expr, distance_expr);
954  }
955  return nullptr;
956 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
SQLOps getOperator() const
Definition: sqldefs.h:69
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::translateGeoConstructor ( const RexFunctionOperator rex_function) const
private

Definition at line 547 of file RelAlgTranslatorGeo.cpp.

References func_resolve, RexFunctionOperator::getName(), and translateGeoFunctionArg().

Referenced by translateFunction().

548  {
549  if (func_resolve(rex_function->getName(),
550  "ST_GeomFromText"sv,
551  "ST_GeogFromText"sv,
552  "ST_Point"sv,
553  "ST_SetSRID"sv)) {
554  SQLTypeInfo arg_ti;
555  int32_t lindex = 0;
556  auto geoargs =
557  translateGeoFunctionArg(rex_function, arg_ti, lindex, false, false, true, true);
558  return makeExpr<Analyzer::GeoExpr>(arg_ti, geoargs);
559  }
560  throw QueryNotSupported(rex_function->getName() +
561  " geo constructor is not supported in this context");
562 }
auto func_resolve
const std::string & getName() 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

+ 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
private

Definition at line 201 of file RelAlgTranslatorGeo.cpp.

References run_benchmark_import::args, CHECK(), CHECK_EQ, fold_expr(), func_resolve, SQLTypeInfo::get_input_srid(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_type(), IS_GEO, kARRAY, kCAST, kDOUBLE, kENCODING_NONE, kGEOGRAPHY, kGEOMETRY, kINT, kLINESTRING, kNULLT, kPOINT, kSMALLINT, kTEXT, kTINYINT, SQLTypeInfo::set_compression(), SQLTypeInfo::set_input_srid(), SQLTypeInfo::set_output_srid(), SQLTypeInfo::set_subtype(), SQLTypeInfo::set_type(), to_string(), translateGeoColumn(), translateGeoLiteral(), translateInput(), translateLiteral(), and translateScalarRex().

Referenced by translateBinaryGeoFunction(), translateFunctionWithGeoArg(), translateGeoConstructor(), and translateUnaryGeoFunction().

208  {
209  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
210 
211  const auto rex_input = dynamic_cast<const RexInput*>(rex_scalar);
212  if (rex_input) {
213  const auto input = translateInput(rex_input);
214  const auto column = dynamic_cast<const Analyzer::ColumnVar*>(input.get());
215  if (!column || !column->get_type_info().is_geometry()) {
216  throw QueryNotSupported("Geo function is expecting a geo column argument");
217  }
218  return translateGeoColumn(
219  rex_input, arg_ti, with_bounds, with_render_group, expand_geo_col);
220  }
221  const auto rex_function = dynamic_cast<const RexFunctionOperator*>(rex_scalar);
222  if (rex_function) {
223  if (rex_function->getName() == "ST_Transform"sv) {
224  CHECK_EQ(size_t(2), rex_function->size());
225  const auto rex_scalar0 =
226  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
227  if (!rex_scalar0) {
228  throw QueryNotSupported(rex_function->getName() + ": unexpected first argument");
229  }
230  auto arg0 = translateGeoFunctionArg(
231  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
232 
233  const auto rex_literal =
234  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
235  if (!rex_literal) {
236  throw QueryNotSupported(rex_function->getName() +
237  ": second argument is expected to be a literal");
238  }
239  const auto e = translateLiteral(rex_literal);
240  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
241  if (!ce || !e->get_type_info().is_integer()) {
242  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
243  }
244  int32_t srid = 0;
245  if (e->get_type_info().get_type() == kSMALLINT) {
246  srid = static_cast<int32_t>(ce->get_constval().smallintval);
247  } else if (e->get_type_info().get_type() == kTINYINT) {
248  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
249  } else if (e->get_type_info().get_type() == kINT) {
250  srid = static_cast<int32_t>(ce->get_constval().intval);
251  } else {
252  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
253  }
254  if (srid != 900913) {
255  throw QueryNotSupported(rex_function->getName() + ": unsupported output SRID " +
256  std::to_string(srid));
257  }
258  if (arg_ti.get_input_srid() > 0) {
259  if (arg_ti.get_input_srid() != 4326) {
260  throw QueryNotSupported(rex_function->getName() + ": unsupported input SRID " +
261  std::to_string(arg_ti.get_input_srid()));
262  }
263  arg_ti.set_output_srid(
264  srid); // We have a valid input SRID, register the output SRID for transform
265  } else {
266  throw QueryNotSupported(rex_function->getName() +
267  ": unexpected input SRID, unable to transform");
268  }
269  return arg0;
270  } else if (func_resolve(
271  rex_function->getName(), "ST_GeomFromText"sv, "ST_GeogFromText"sv)) {
272  CHECK(rex_function->size() == size_t(1) || rex_function->size() == size_t(2));
273  // First - register srid, then send it to geo literal translation
274  int32_t srid = 0;
275  if (rex_function->size() == 2) {
276  const auto rex_literal =
277  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
278  if (!rex_literal) {
279  throw QueryNotSupported(rex_function->getName() +
280  ": second argument is expected to be a literal");
281  }
282  const auto e = translateLiteral(rex_literal);
283  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
284  if (!ce || !e->get_type_info().is_integer()) {
285  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
286  }
287  if (e->get_type_info().get_type() == kSMALLINT) {
288  srid = static_cast<int32_t>(ce->get_constval().smallintval);
289  } else if (e->get_type_info().get_type() == kTINYINT) {
290  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
291  } else if (e->get_type_info().get_type() == kINT) {
292  srid = static_cast<int32_t>(ce->get_constval().intval);
293  } else {
294  throw QueryNotSupported(rex_function->getName() + " expecting integer SRID");
295  }
296  if (srid != 0 && srid != 4326 && srid != 900913) {
297  throw QueryNotSupported(rex_function->getName() + ": unsupported SRID " +
298  std::to_string(srid));
299  }
300  }
301  arg_ti.set_input_srid(srid); // Input SRID
302  arg_ti.set_output_srid(srid); // Output SRID is the same - no transform
303 
304  const auto rex_literal =
305  dynamic_cast<const RexLiteral*>(rex_function->getOperand(0));
306  if (!rex_literal) {
307  throw QueryNotSupported(rex_function->getName() +
308  " expects a string literal as first argument");
309  }
310  auto arg0 = translateGeoLiteral(rex_literal, arg_ti, with_bounds);
311  arg_ti.set_subtype((rex_function->getName() == "ST_GeogFromText"sv) ? kGEOGRAPHY
312  : kGEOMETRY);
313  return arg0;
314  } else if (rex_function->getName() == "ST_PointN"sv) {
315  CHECK_EQ(size_t(2), rex_function->size());
316  const auto rex_scalar0 =
317  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
318  if (!rex_scalar0) {
319  throw QueryNotSupported(rex_function->getName() +
320  ": expects scalar as first argument");
321  }
322  auto arg0 = translateGeoFunctionArg(
323  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
324  if (arg_ti.get_type() != kLINESTRING) {
325  throw QueryNotSupported(rex_function->getName() +
326  " expects LINESTRING as first argument");
327  }
328  const auto rex_literal =
329  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
330  if (!rex_literal) {
331  throw QueryNotSupported(rex_function->getName() +
332  ": second argument is expected to be a literal");
333  }
334  const auto e = translateLiteral(rex_literal);
335  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
336  if (!ce || !e->get_type_info().is_integer()) {
337  throw QueryNotSupported(rex_function->getName() +
338  ": expecting integer index as second argument");
339  }
340  int32_t index = 0;
341  if (e->get_type_info().get_type() == kSMALLINT) {
342  index = static_cast<int32_t>(ce->get_constval().smallintval);
343  } else if (e->get_type_info().get_type() == kTINYINT) {
344  index = static_cast<int32_t>(ce->get_constval().tinyintval);
345  } else if (e->get_type_info().get_type() == kINT) {
346  index = static_cast<int32_t>(ce->get_constval().intval);
347  } else {
348  throw QueryNotSupported(rex_function->getName() + " expecting integer index");
349  }
350  if (lindex != 0) {
351  throw QueryNotSupported(rex_function->getName() +
352  ": LINESTRING is already indexed");
353  }
354  if (index == 0) {
355  throw QueryNotSupported(rex_function->getName() + ": invalid index");
356  }
357  lindex = index;
358  return arg0;
359  } else if (rex_function->getName() == "ST_StartPoint"sv) {
360  CHECK_EQ(size_t(1), rex_function->size());
361  const auto rex_scalar0 =
362  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
363  if (!rex_scalar0) {
364  throw QueryNotSupported(rex_function->getName() +
365  ": expects scalar as first argument");
366  }
367  auto arg0 = translateGeoFunctionArg(
368  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
369  if (arg_ti.get_type() != kLINESTRING) {
370  throw QueryNotSupported(rex_function->getName() +
371  " expects LINESTRING as first argument");
372  }
373  if (lindex != 0) {
374  throw QueryNotSupported(rex_function->getName() +
375  ": LINESTRING is already indexed");
376  }
377  lindex = 1;
378  return arg0;
379  } else if (rex_function->getName() == "ST_EndPoint"sv) {
380  CHECK_EQ(size_t(1), rex_function->size());
381  const auto rex_scalar0 =
382  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
383  if (!rex_scalar0) {
384  throw QueryNotSupported(rex_function->getName() +
385  ": expects scalar as first argument");
386  }
387  auto arg0 = translateGeoFunctionArg(
388  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
389  if (arg_ti.get_type() != kLINESTRING) {
390  throw QueryNotSupported(rex_function->getName() +
391  " expects LINESTRING as first argument");
392  }
393  if (lindex != 0) {
394  throw QueryNotSupported(rex_function->getName() +
395  ": LINESTRING is already indexed");
396  }
397  lindex = -1;
398  return arg0;
399  } else if (rex_function->getName() == "ST_SRID"sv) {
400  CHECK_EQ(size_t(1), rex_function->size());
401  const auto rex_scalar0 =
402  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
403  if (!rex_scalar0) {
404  throw QueryNotSupported(rex_function->getName() +
405  ": expects scalar as first argument");
406  }
407  auto arg0 = translateGeoFunctionArg(
408  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
409  if (!IS_GEO(arg_ti.get_type())) {
410  throw QueryNotSupported(rex_function->getName() + " expects geometry argument");
411  }
412  return arg0;
413  } else if (rex_function->getName() == "ST_SetSRID"sv) {
414  CHECK_EQ(size_t(2), rex_function->size());
415  const auto rex_scalar0 =
416  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
417  if (!rex_scalar0) {
418  throw QueryNotSupported(rex_function->getName() +
419  ": expects scalar as first argument");
420  }
421  auto arg0 = translateGeoFunctionArg(rex_scalar0,
422  arg_ti,
423  lindex,
424  with_bounds,
425  with_render_group,
426  expand_geo_col,
427  is_projection);
428  if (!IS_GEO(arg_ti.get_type())) {
429  throw QueryNotSupported(rex_function->getName() + " expects geometry argument");
430  }
431  const auto rex_literal =
432  dynamic_cast<const RexLiteral*>(rex_function->getOperand(1));
433  if (!rex_literal) {
434  throw QueryNotSupported(rex_function->getName() +
435  ": second argument is expected to be a literal");
436  }
437  const auto e = translateLiteral(rex_literal);
438  auto ce = std::dynamic_pointer_cast<Analyzer::Constant>(e);
439  if (!ce || !e->get_type_info().is_integer()) {
440  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
441  }
442  int32_t srid = 0;
443  if (e->get_type_info().get_type() == kSMALLINT) {
444  srid = static_cast<int32_t>(ce->get_constval().smallintval);
445  } else if (e->get_type_info().get_type() == kTINYINT) {
446  srid = static_cast<int32_t>(ce->get_constval().tinyintval);
447  } else if (e->get_type_info().get_type() == kINT) {
448  srid = static_cast<int32_t>(ce->get_constval().intval);
449  } else {
450  throw QueryNotSupported(rex_function->getName() + ": expecting integer SRID");
451  }
452  arg_ti.set_input_srid(srid); // Input SRID
453  arg_ti.set_output_srid(srid); // Output SRID is the same - no transform
454  return arg0;
455  } else if (rex_function->getName() == "CastToGeography"sv) {
456  CHECK_EQ(size_t(1), rex_function->size());
457  const auto rex_scalar0 =
458  dynamic_cast<const RexScalar*>(rex_function->getOperand(0));
459  if (!rex_scalar0) {
460  throw QueryNotSupported(rex_function->getName() +
461  ": expects scalar as first argument");
462  }
463  auto arg0 = translateGeoFunctionArg(
464  rex_scalar0, arg_ti, lindex, with_bounds, with_render_group, expand_geo_col);
465  if (!IS_GEO(arg_ti.get_type())) {
466  throw QueryNotSupported(rex_function->getName() + " expects geometry argument");
467  }
468  if (arg_ti.get_output_srid() != 4326) {
469  throw QueryNotSupported(rex_function->getName() +
470  " expects geometry with SRID=4326");
471  }
472  arg_ti.set_subtype(kGEOGRAPHY);
473  return arg0;
474  } else if (rex_function->getName() == "ST_Point"sv) {
475  CHECK_EQ(size_t(2), rex_function->size());
476  arg_ti.set_type(kPOINT);
477  arg_ti.set_subtype(kGEOMETRY);
478  arg_ti.set_input_srid(0);
479  arg_ti.set_output_srid(0);
481 
482  auto coord1 = translateScalarRex(rex_function->getOperand(0));
483  auto coord2 = translateScalarRex(rex_function->getOperand(1));
484  auto d_ti = SQLTypeInfo(kDOUBLE, true);
485  auto cast_coord1 = coord1->add_cast(d_ti);
486  auto cast_coord2 = coord2->add_cast(d_ti);
487  // First try to fold to geo literal
488  auto fold1 = fold_expr(cast_coord1.get());
489  auto fold2 = fold_expr(cast_coord2.get());
490  auto const_coord1 = std::dynamic_pointer_cast<Analyzer::Constant>(fold1);
491  auto const_coord2 = std::dynamic_pointer_cast<Analyzer::Constant>(fold2);
492  if (const_coord1 && const_coord2) {
493  CHECK(const_coord1->get_type_info().get_type() == kDOUBLE);
494  CHECK(const_coord2->get_type_info().get_type() == kDOUBLE);
495  std::string wkt = "POINT(" +
496  std::to_string(const_coord1->get_constval().doubleval) + " " +
497  std::to_string(const_coord2->get_constval().doubleval) + ")";
498  RexLiteral rex_literal{wkt, kTEXT, kNULLT, 0, 0, 0, 0};
499  auto args = translateGeoLiteral(&rex_literal, arg_ti, false);
500  CHECK(arg_ti.get_type() == kPOINT);
501  return args;
502  }
503  // Couldn't fold to geo literal, construct on the fly
504  auto da_ti = SQLTypeInfo(kARRAY, true);
505  da_ti.set_subtype(kDOUBLE);
506  da_ti.set_size(16);
507  auto cast_coords = {cast_coord1, cast_coord2};
508  auto is_local_alloca = !is_projection;
509  auto ae =
510  makeExpr<Analyzer::ArrayExpr>(da_ti, cast_coords, 0, false, is_local_alloca);
511  // cast it to tinyint[16]
512  SQLTypeInfo tia_ti = SQLTypeInfo(kARRAY, true);
513  tia_ti.set_subtype(kTINYINT);
514  tia_ti.set_size(16);
515  return {makeExpr<Analyzer::UOper>(tia_ti, false, kCAST, ae)};
516  } else {
517  throw QueryNotSupported("Unsupported argument: " + rex_function->getName());
518  }
519  }
520  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex_scalar);
521  if (rex_literal) {
522  return translateGeoLiteral(rex_literal, arg_ti, with_bounds);
523  }
524  throw QueryNotSupported("Geo function argument not supported");
525 }
void set_compression(EncodingType c)
Definition: sqltypes.h:348
#define CHECK_EQ(x, y)
Definition: Logger.h:205
auto func_resolve
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
HOST DEVICE void set_subtype(SQLTypes st)
Definition: sqltypes.h:339
Definition: sqldefs.h:49
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:248
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:342
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
CHECK(cgen_state)
void set_output_srid(int s)
Definition: sqltypes.h:344
Definition: sqltypes.h:53
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:252
Definition: sqltypes.h:46
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:163
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
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
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:254
HOST DEVICE void set_type(SQLTypes t)
Definition: sqltypes.h:338

+ 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 106 of file RelAlgTranslatorGeo.cpp.

References run_benchmark_import::args, CHECK(), geospatial::compress_coords(), Datum::doubleval, SQLTypeInfo::get_compression(), SQLTypeInfo::get_output_srid(), SQLTypeInfo::get_type(), Geo_namespace::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().

109  {
110  CHECK(rex_literal);
111  if (rex_literal->getType() != kTEXT) {
112  throw std::runtime_error("Geo literals must be strings");
113  }
114  const auto e = translateLiteral(rex_literal);
115  auto wkt = std::dynamic_pointer_cast<Analyzer::Constant>(e);
116  CHECK(wkt);
117  std::vector<double> coords;
118  std::vector<double> bounds;
119  std::vector<int> ring_sizes;
120  std::vector<int> poly_rings;
121  int32_t srid = ti.get_output_srid();
123  *wkt->get_constval().stringval, ti, coords, bounds, ring_sizes, poly_rings)) {
124  throw QueryNotSupported("Could not read geometry from text");
125  }
127  ti.set_input_srid(srid);
128  ti.set_output_srid(srid);
129  // Compress geo literals by default
130  if (srid == 4326) {
132  ti.set_comp_param(32);
133  }
134 
135  std::vector<std::shared_ptr<Analyzer::Expr>> args;
136 
137  std::vector<uint8_t> compressed_coords = geospatial::compress_coords(coords, ti);
138  std::list<std::shared_ptr<Analyzer::Expr>> compressed_coords_exprs;
139  for (auto cc : compressed_coords) {
140  Datum d;
141  d.tinyintval = cc;
142  auto e = makeExpr<Analyzer::Constant>(kTINYINT, false, d);
143  compressed_coords_exprs.push_back(e);
144  }
145  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
146  arr_ti.set_subtype(kTINYINT);
147  arr_ti.set_size(compressed_coords.size() * sizeof(int8_t));
148  arr_ti.set_compression(ti.get_compression());
149  arr_ti.set_comp_param((ti.get_compression() == kENCODING_GEOINT) ? 32 : 64);
150  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, compressed_coords_exprs));
151 
152  auto lit_type = ti.get_type();
153  if (lit_type == kPOLYGON || lit_type == kMULTIPOLYGON) {
154  // ring sizes
155  std::list<std::shared_ptr<Analyzer::Expr>> ring_size_exprs;
156  for (auto c : ring_sizes) {
157  Datum d;
158  d.intval = c;
159  auto e = makeExpr<Analyzer::Constant>(kINT, false, d);
160  ring_size_exprs.push_back(e);
161  }
162  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
163  arr_ti.set_subtype(kINT);
164  arr_ti.set_size(ring_sizes.size() * sizeof(int32_t));
165  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, ring_size_exprs));
166 
167  // poly rings
168  if (lit_type == kMULTIPOLYGON) {
169  std::list<std::shared_ptr<Analyzer::Expr>> poly_rings_exprs;
170  for (auto c : poly_rings) {
171  Datum d;
172  d.intval = c;
173  auto e = makeExpr<Analyzer::Constant>(kINT, false, d);
174  poly_rings_exprs.push_back(e);
175  }
176  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
177  arr_ti.set_subtype(kINT);
178  arr_ti.set_size(poly_rings.size() * sizeof(int32_t));
179  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, poly_rings_exprs));
180  }
181  }
182 
183  if (with_bounds && ti.has_bounds()) {
184  // bounds
185  std::list<std::shared_ptr<Analyzer::Expr>> bounds_exprs;
186  for (auto b : bounds) {
187  Datum d;
188  d.doubleval = b;
189  auto e = makeExpr<Analyzer::Constant>(kDOUBLE, false, d);
190  bounds_exprs.push_back(e);
191  }
192  SQLTypeInfo arr_ti = SQLTypeInfo(kARRAY, true);
193  arr_ti.set_subtype(kDOUBLE);
194  arr_ti.set_size(bounds.size() * sizeof(double));
195  args.push_back(makeExpr<Analyzer::Constant>(arr_ti, false, bounds_exprs));
196  }
197 
198  return args;
199 }
int8_t tinyintval
Definition: sqltypes.h:124
void set_compression(EncodingType c)
Definition: sqltypes.h:348
void set_size(int s)
Definition: sqltypes.h:346
HOST DEVICE void set_subtype(SQLTypes st)
Definition: sqltypes.h:339
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:248
int32_t intval
Definition: sqltypes.h:126
void set_input_srid(int d)
Definition: sqltypes.h:342
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
CHECK(cgen_state)
bool has_bounds() const
Definition: sqltypes.h:317
void set_output_srid(int s)
Definition: sqltypes.h:344
void set_comp_param(int p)
Definition: sqltypes.h:349
Definition: sqltypes.h:53
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:256
static bool getGeoColumns(const std::string &wkt, 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: geo_types.cpp:459
std::vector< uint8_t > compress_coords(std::vector< double > &coords, const SQLTypeInfo &ti)
Definition: sqltypes.h:46
double doubleval
Definition: sqltypes.h:129
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:254

+ 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 1077 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().

1078  {
1079  CHECK_EQ(rex_operator->size(), 2u);
1080 
1081  auto translate_input =
1082  [&](const RexScalar* operand) -> std::shared_ptr<Analyzer::Expr> {
1083  const auto input = dynamic_cast<const RexInput*>(operand);
1084  CHECK(input);
1085 
1086  SQLTypeInfo ti;
1087  const auto exprs = translateGeoColumn(input, ti, true, false, false);
1088  CHECK_GT(exprs.size(), 0u);
1089  if (ti.get_type() == kPOINT) {
1090  return exprs.front();
1091  } else {
1092  return exprs.back();
1093  }
1094  };
1095 
1096  SQLQualifier sql_qual{kONE};
1097  SQLOps sql_op{kOVERLAPS};
1098  return makeExpr<Analyzer::BinOper>(SQLTypeInfo(kBOOLEAN, false),
1099  false,
1100  sql_op,
1101  sql_qual,
1102  translate_input(rex_operator->getOperand(1)),
1103  translate_input(rex_operator->getOperand(0)));
1104 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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:248
#define CHECK_GT(x, y)
Definition: Logger.h:209
CHECK(cgen_state)
Definition: sqldefs.h:69
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::translateHPTLiteral ( const RexFunctionOperator rex_function) const
private

Definition at line 1715 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1716  {
1717  /* since calcite uses Avatica package called DateTimeUtils to parse timestamp strings.
1718  Therefore any string having fractional seconds more 3 places after the decimal
1719  (milliseconds) will get truncated to 3 decimal places, therefore we lose precision
1720  (us|ns). Issue: [BE-2461] Here we are hijacking literal cast to Timestamp(6|9) from
1721  calcite and translating them to generate our own casts.
1722  */
1723  CHECK_EQ(size_t(1), rex_function->size());
1724  const auto operand = translateScalarRex(rex_function->getOperand(0));
1725  const auto& operand_ti = operand->get_type_info();
1726  const auto& target_ti = rex_function->getType();
1727  if (!operand_ti.is_string()) {
1728  throw std::runtime_error(
1729  "High precision timestamp cast argument must be a string. Input type is: " +
1730  operand_ti.get_type_name());
1731  } else if (!target_ti.is_high_precision_timestamp()) {
1732  throw std::runtime_error(
1733  "Cast target type should be high precision timestamp. Input type is: " +
1734  target_ti.get_type_name());
1735  } else if (target_ti.get_dimension() != 6 && target_ti.get_dimension() != 9) {
1736  throw std::runtime_error(
1737  "Cast target type should be TIMESTAMP(6|9). Input type is: TIMESTAMP(" +
1738  std::to_string(target_ti.get_dimension()) + ")");
1739  } else {
1740  return operand->add_cast(target_ti);
1741  }
1742 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 516 of file RelAlgTranslator.cpp.

References CHECK(), CHECK_EQ, 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().

517  {
518  if (just_explain_) {
519  throw std::runtime_error("EXPLAIN is not supported with sub-queries");
520  }
521  CHECK(rex_operator->size() == 2);
522  const auto lhs = translateScalarRex(rex_operator->getOperand(0));
523  const auto rhs = rex_operator->getOperand(1);
524  const auto rex_subquery = dynamic_cast<const RexSubQuery*>(rhs);
525  CHECK(rex_subquery);
526  auto ti = lhs->get_type_info();
527  auto result = rex_subquery->getExecutionResult();
528  auto& row_set = result->getRows();
529  CHECK_EQ(size_t(1), row_set->colCount());
530  const auto& rhs_ti = row_set->getColType(0);
531  if (rhs_ti.get_type() != ti.get_type()) {
532  throw std::runtime_error(
533  "The two sides of the IN operator must have the same type; found " +
534  ti.get_type_name() + " and " + rhs_ti.get_type_name());
535  }
536  row_set->moveToBegin();
537  if (row_set->entryCount() > 10000) {
538  std::shared_ptr<Analyzer::Expr> expr;
539  if ((ti.is_integer() || (ti.is_string() && ti.get_compression() == kENCODING_DICT)) &&
540  !row_set->getQueryMemDesc().didOutputColumnar()) {
541  expr = getInIntegerSetExpr(lhs, *row_set);
542  // Handle the highly unlikely case when the InIntegerSet ended up being tiny.
543  // Just let it fall through the usual InValues path at the end of this method,
544  // its codegen knows to use inline comparisons for few values.
545  if (expr && std::static_pointer_cast<Analyzer::InIntegerSet>(expr)
546  ->get_value_list()
547  .size() <= 100) {
548  expr = nullptr;
549  }
550  } else {
551  expr = get_in_values_expr(lhs, *row_set);
552  }
553  if (expr) {
554  return expr;
555  }
556  }
557  std::list<std::shared_ptr<Analyzer::Expr>> value_exprs;
558  while (true) {
559  auto row = row_set->getNextRow(true, false);
560  if (row.empty()) {
561  break;
562  }
563  if (g_enable_watchdog && value_exprs.size() >= 10000) {
564  throw std::runtime_error(
565  "Unable to handle 'expr IN (subquery)', subquery returned 10000+ rows.");
566  }
567  auto scalar_tv = boost::get<ScalarTargetValue>(&row[0]);
568  Datum d{0};
569  bool is_null_const{false};
570  std::tie(d, is_null_const) = datum_from_scalar_tv(scalar_tv, ti);
571  if (ti.is_string() && ti.get_compression() != kENCODING_NONE) {
572  auto ti_none_encoded = ti;
573  ti_none_encoded.set_compression(kENCODING_NONE);
574  auto none_encoded_string = makeExpr<Analyzer::Constant>(ti, is_null_const, d);
575  auto dict_encoded_string =
576  std::make_shared<Analyzer::UOper>(ti, false, kCAST, none_encoded_string);
577  value_exprs.push_back(dict_encoded_string);
578  } else {
579  value_exprs.push_back(makeExpr<Analyzer::Constant>(ti, is_null_const, d));
580  }
581  }
582  return makeExpr<Analyzer::InValues>(lhs, value_exprs);
583 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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
bool g_enable_watchdog
CHECK(cgen_state)
std::shared_ptr< Analyzer::Expr > get_in_values_expr(std::shared_ptr< Analyzer::Expr > arg, const ResultSet &val_set)
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 348 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().

349  {
350  const auto source = rex_input->getSourceNode();
351  const auto it_rte_idx = input_to_nest_level_.find(source);
352  CHECK(it_rte_idx != input_to_nest_level_.end());
353  const int rte_idx = it_rte_idx->second;
354  const auto scan_source = dynamic_cast<const RelScan*>(source);
355  const auto& in_metainfo = source->getOutputMetainfo();
356  if (scan_source) {
357  // We're at leaf (scan) level and not supposed to have input metadata,
358  // the name and type information come directly from the catalog.
359  CHECK(in_metainfo.empty());
360  const auto table_desc = scan_source->getTableDescriptor();
361  const auto cd =
362  cat_.getMetadataForColumnBySpi(table_desc->tableId, rex_input->getIndex() + 1);
363  CHECK(cd);
364  auto col_ti = cd->columnType;
365  if (col_ti.is_string()) {
366  col_ti.set_type(kTEXT);
367  }
368  if (cd->isVirtualCol) {
369  // TODO(alex): remove at some point, we only need this fixup for backwards
370  // compatibility with old imported data
371  CHECK_EQ("rowid", cd->columnName);
372  col_ti.set_size(8);
373  }
374  CHECK_LE(static_cast<size_t>(rte_idx), join_types_.size());
375  if (rte_idx > 0 && join_types_[rte_idx - 1] == JoinType::LEFT) {
376  col_ti.set_notnull(false);
377  }
378  return std::make_shared<Analyzer::ColumnVar>(
379  col_ti, table_desc->tableId, cd->columnId, rte_idx);
380  }
381  CHECK(!in_metainfo.empty());
382  CHECK_GE(rte_idx, 0);
383  const size_t col_id = rex_input->getIndex();
384  CHECK_LT(col_id, in_metainfo.size());
385  auto col_ti = in_metainfo[col_id].get_type_info();
386  CHECK_LE(static_cast<size_t>(rte_idx), join_types_.size());
387  if (rte_idx > 0 && join_types_[rte_idx - 1] == JoinType::LEFT) {
388  col_ti.set_notnull(false);
389  }
390  return std::make_shared<Analyzer::ColumnVar>(col_ti, -source->getId(), col_id, rte_idx);
391 }
const std::vector< JoinType > join_types_
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define CHECK_GE(x, y)
Definition: Logger.h:210
unsigned getIndex() const
CHECK(cgen_state)
const ColumnDescriptor * getMetadataForColumnBySpi(const int tableId, const size_t spi) const
Definition: Catalog.cpp:1531
const std::unordered_map< const RelAlgNode *, int > input_to_nest_level_
#define CHECK_LT(x, y)
Definition: Logger.h:207
Definition: sqltypes.h:53
#define CHECK_LE(x, y)
Definition: Logger.h:208
const RelAlgNode * getSourceNode() const
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 1249 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1250  {
1251  CHECK_EQ(size_t(2), rex_function->size());
1252  const auto base = translateScalarRex(rex_function->getOperand(0));
1253  const auto index = translateScalarRex(rex_function->getOperand(1));
1254  return makeExpr<Analyzer::BinOper>(
1255  base->get_type_info().get_elem_type(), false, kARRAY_AT, kONE, base, index);
1256 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 1194 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1195  {
1196  const auto& args = translateFunctionArgs(rex_function);
1197  CHECK_EQ(size_t(1), args.size());
1198  const auto expr = dynamic_cast<Analyzer::Expr*>(args[0].get());
1199  if (nullptr == expr || !expr->get_type_info().is_string() ||
1200  expr->get_type_info().is_varlen()) {
1201  throw std::runtime_error(rex_function->getName() +
1202  " expects a dictionary encoded text column.");
1203  }
1204  return makeExpr<Analyzer::KeyForStringExpr>(args[0]);
1205 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 1186 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1187  {
1188  CHECK_EQ(size_t(1), rex_function->size());
1189  const auto str_arg = translateScalarRex(rex_function->getOperand(0));
1190  return makeExpr<Analyzer::CharLengthExpr>(str_arg->decompress(),
1191  rex_function->getName() == "CHAR_LENGTH"sv);
1192 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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 905 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

906  {
907  CHECK(rex_function->size() == 2 || rex_function->size() == 3);
908  const auto arg = translateScalarRex(rex_function->getOperand(0));
909  const auto like = translateScalarRex(rex_function->getOperand(1));
910  if (!std::dynamic_pointer_cast<const Analyzer::Constant>(like)) {
911  throw std::runtime_error("The matching pattern must be a literal.");
912  }
913  const auto escape = (rex_function->size() == 3)
914  ? translateScalarRex(rex_function->getOperand(2))
915  : nullptr;
916  const bool is_ilike = rex_function->getName() == "PG_ILIKE"sv;
917  return Parser::LikeExpr::get(arg, like, escape, is_ilike, false);
918 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
CHECK(cgen_state)
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:528
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 934 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

935  {
936  CHECK(rex_function->size() == 1);
937  const auto arg = translateScalarRex(rex_function->getOperand(0));
938  return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.9375);
939 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
CHECK(cgen_state)

+ 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 249 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(), Datum::doubleval, logger::FATAL, kBOOLEAN, kDATE, kDECIMAL, kDOUBLE, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kNULLT, kTEXT, kTIME, kTIMESTAMP, LOG, and make_fp_constant().

Referenced by RelAlgExecutor::executeLogicalValues(), translateGeoFunctionArg(), translateGeoLiteral(), and translateScalarRex().

250  {
251  auto lit_ti = build_type_info(
252  rex_literal->getType(), rex_literal->getScale(), rex_literal->getPrecision());
253  auto target_ti = build_type_info(rex_literal->getTargetType(),
254  rex_literal->getTypeScale(),
255  rex_literal->getTypePrecision());
256  switch (rex_literal->getType()) {
257  case kDECIMAL: {
258  const auto val = rex_literal->getVal<int64_t>();
259  const int precision = rex_literal->getPrecision();
260  const int scale = rex_literal->getScale();
261  if (target_ti.is_fp() && !scale) {
262  return make_fp_constant(val, target_ti);
263  }
264  auto lit_expr = scale ? Parser::FixedPtLiteral::analyzeValue(val, scale, precision)
265  : Parser::IntLiteral::analyzeValue(val);
266  return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
267  }
268  case kTEXT: {
269  return Parser::StringLiteral::analyzeValue(rex_literal->getVal<std::string>());
270  }
271  case kBOOLEAN: {
272  Datum d;
273  d.boolval = rex_literal->getVal<bool>();
274  return makeExpr<Analyzer::Constant>(kBOOLEAN, false, d);
275  }
276  case kDOUBLE: {
277  Datum d;
278  d.doubleval = rex_literal->getVal<double>();
279  auto lit_expr = makeExpr<Analyzer::Constant>(kDOUBLE, false, d);
280  return lit_ti != target_ti ? lit_expr->add_cast(target_ti) : lit_expr;
281  }
282  case kINTERVAL_DAY_TIME:
283  case kINTERVAL_YEAR_MONTH: {
284  Datum d;
285  d.bigintval = rex_literal->getVal<int64_t>();
286  return makeExpr<Analyzer::Constant>(rex_literal->getType(), false, d);
287  }
288  case kTIME:
289  case kTIMESTAMP: {
290  Datum d;
291  d.bigintval =
292  rex_literal->getType() == kTIMESTAMP && rex_literal->getPrecision() > 0
293  ? rex_literal->getVal<int64_t>()
294  : rex_literal->getVal<int64_t>() / 1000;
295  return makeExpr<Analyzer::Constant>(
296  SQLTypeInfo(rex_literal->getType(), rex_literal->getPrecision(), 0, false),
297  false,
298  d);
299  }
300  case kDATE: {
301  Datum d;
302  d.bigintval = rex_literal->getVal<int64_t>() * 24 * 3600;
303  return makeExpr<Analyzer::Constant>(rex_literal->getType(), false, d);
304  }
305  case kNULLT: {
306  if (target_ti.is_array()) {
308  // defaulting to valid sub-type for convenience
309  target_ti.set_subtype(kBOOLEAN);
310  return makeExpr<Analyzer::ArrayExpr>(target_ti, args, -1, true);
311  }
312  return makeExpr<Analyzer::Constant>(rex_literal->getTargetType(), true, Datum{0});
313  }
314  default: {
315  LOG(FATAL) << "Unexpected literal type " << lit_ti.get_type_name();
316  }
317  }
318  return nullptr;
319 }
Definition: sqltypes.h:50
#define LOG(tag)
Definition: Logger.h:188
bool boolval
Definition: sqltypes.h:123
int64_t bigintval
Definition: sqltypes.h:127
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:95
Definition: sqltypes.h:53
Definition: sqltypes.h:54
static std::shared_ptr< Analyzer::Expr > analyzeValue(const int64_t numericval, const int scale, const int precision)
Definition: ParserNode.cpp:135
std::shared_ptr< Analyzer::Constant > make_fp_constant(const int64_t val, const SQLTypeInfo &ti)
std::vector< ExpressionPtr > ExpressionPtrVector
Definition: Analyzer.h:182
double doubleval
Definition: sqltypes.h:129

+ 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 1207 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

1208  {
1209  const auto& args = translateFunctionArgs(rex_function);
1210  CHECK_EQ(size_t(1), args.size());
1211  CHECK(args[0]);
1212 
1213  if (args[0]->get_type_info().is_dict_encoded_string() ||
1214  dynamic_cast<Analyzer::Constant*>(args[0].get())) {
1215  return makeExpr<Analyzer::LowerExpr>(args[0]);
1216  }
1217 
1218  throw std::runtime_error(rex_function->getName() +
1219  " expects a dictionary encoded text column or a literal.");
1220 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CHECK(cgen_state)
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::translateNow ( ) const
private

Definition at line 1258 of file RelAlgTranslator.cpp.

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

Referenced by translateDatetime(), and translateFunction().

1258  {
1260 }
static std::shared_ptr< Analyzer::Expr > get(const int64_t)
Definition: ParserNode.cpp:171

+ 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 1316 of file RelAlgTranslator.cpp.

Referenced by translateFunction().

1316  {
1317  return makeExpr<Analyzer::OffsetInFragment>();
1318 }

+ Here is the caller graph for this function:

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

Definition at line 835 of file RelAlgTranslator.cpp.

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

Referenced by translateScalarRex().

836  {
837  CHECK_GT(rex_operator->size(), size_t(0));
838  if (rex_operator->size() == 1) {
839  return translateUoper(rex_operator);
840  }
841  const auto sql_op = rex_operator->getOperator();
842  if (sql_op == kIN) {
843  return translateInOper(rex_operator);
844  }
845  if (sql_op == kMINUS || sql_op == kPLUS) {
846  auto date_plus_minus = translateDatePlusMinus(rex_operator);
847  if (date_plus_minus) {
848  return date_plus_minus;
849  }
850  }
851  if (sql_op == kOVERLAPS) {
852  return translateOverlapsOper(rex_operator);
853  } else if (IS_COMPARISON(sql_op)) {
854  auto geo_comp = translateGeoComparison(rex_operator);
855  if (geo_comp) {
856  return geo_comp;
857  }
858  }
859  auto lhs = translateScalarRex(rex_operator->getOperand(0));
860  for (size_t i = 1; i < rex_operator->size(); ++i) {
861  std::shared_ptr<Analyzer::Expr> rhs;
862  SQLQualifier sql_qual{kONE};
863  const auto rhs_op = rex_operator->getOperand(i);
864  std::tie(rhs, sql_qual) = get_quantified_rhs(rhs_op, *this);
865  if (!rhs) {
866  rhs = translateScalarRex(rhs_op);
867  }
868  CHECK(rhs);
869  lhs = Parser::OperExpr::normalize(sql_op, sql_qual, lhs, rhs);
870  }
871  return lhs;
872 }
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:209
SQLOps getOperator() const
CHECK(cgen_state)
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:259
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
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 874 of file RelAlgTranslator.cpp.

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

Referenced by translateOper().

875  {
876  const auto sql_op = rex_operator->getOperator();
877  CHECK(sql_op == kOVERLAPS);
878 
879  const auto lhs = translateScalarRex(rex_operator->getOperand(0));
880  const auto lhs_ti = lhs->get_type_info();
881  if (lhs_ti.is_geometry()) {
882  return translateGeoOverlapsOper(rex_operator);
883  } else {
884  throw std::runtime_error(
885  "Overlaps equivalence is currently only supported for geospatial types");
886  }
887 }
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
CHECK(cgen_state)

+ 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 920 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

921  {
922  CHECK(rex_function->size() == 2 || rex_function->size() == 3);
923  const auto arg = translateScalarRex(rex_function->getOperand(0));
924  const auto pattern = translateScalarRex(rex_function->getOperand(1));
925  if (!std::dynamic_pointer_cast<const Analyzer::Constant>(pattern)) {
926  throw std::runtime_error("The matching pattern must be a literal.");
927  }
928  const auto escape = (rex_function->size() == 3)
929  ? translateScalarRex(rex_function->getOperand(2))
930  : nullptr;
931  return Parser::RegexpExpr::get(arg, pattern, escape, false);
932 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
CHECK(cgen_state)
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:623

+ 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 169 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(), translateCardinality(), translateCase(), translateDateadd(), translateDatediff(), translateDatepart(), translateDatePlusMinus(), translateDatetime(), translateExtract(), translateFunction(), translateFunctionArgs(), translateFunctionWithGeoArg(), translateGeoComparison(), translateGeoFunctionArg(), translateHPTLiteral(), translateInOper(), translateItem(), translateLength(), translateLike(), translateLikely(), translateOper(), translateOverlapsOper(), translateRegexp(), translateSign(), translateTernaryGeoFunction(), translateUnlikely(), translateUoper(), and translateWindowFunction().

170  {
171  const auto rex_input = dynamic_cast<const RexInput*>(rex);
172  if (rex_input) {
173  return translateInput(rex_input);
174  }
175  const auto rex_literal = dynamic_cast<const RexLiteral*>(rex);
176  if (rex_literal) {
177  return translateLiteral(rex_literal);
178  }
179  const auto rex_window_function = dynamic_cast<const RexWindowFunctionOperator*>(rex);
180  if (rex_window_function) {
181  return translateWindowFunction(rex_window_function);
182  }
183  const auto rex_function = dynamic_cast<const RexFunctionOperator*>(rex);
184  if (rex_function) {
185  return translateFunction(rex_function);
186  }
187  const auto rex_operator = dynamic_cast<const RexOperator*>(rex);
188  if (rex_operator) {
189  return translateOper(rex_operator);
190  }
191  const auto rex_case = dynamic_cast<const RexCase*>(rex);
192  if (rex_case) {
193  return translateCase(rex_case);
194  }
195  const auto rex_subquery = dynamic_cast<const RexSubQuery*>(rex);
196  if (rex_subquery) {
197  return translateScalarSubquery(rex_subquery);
198  }
199  CHECK(false);
200  return nullptr;
201 }
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 *)
CHECK(cgen_state)
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 321 of file RelAlgTranslator.cpp.

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

Referenced by translateScalarRex().

322  {
323  if (just_explain_) {
324  throw std::runtime_error("EXPLAIN is not supported with sub-queries");
325  }
326  CHECK(rex_subquery);
327  auto result = rex_subquery->getExecutionResult();
328  auto row_set = result->getRows();
329  if (row_set->rowCount() > size_t(1)) {
330  throw std::runtime_error("Scalar sub-query returned multiple rows");
331  }
332  if (row_set->rowCount() < size_t(1)) {
333  CHECK_EQ(row_set->rowCount(), size_t(0));
334  throw std::runtime_error("Scalar sub-query returned no results");
335  }
336  auto first_row = row_set->getNextRow(false, false);
337  auto scalar_tv = boost::get<ScalarTargetValue>(&first_row[0]);
338  auto ti = rex_subquery->getType();
339  if (ti.is_string()) {
340  throw std::runtime_error("Scalar sub-queries which return strings not supported");
341  }
342  Datum d{0};
343  bool is_null_const{false};
344  std::tie(d, is_null_const) = datum_from_scalar_tv(scalar_tv, ti);
345  return makeExpr<Analyzer::Constant>(ti, is_null_const, d);
346 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CHECK(cgen_state)
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 1294 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().

1295  {
1296  std::list<std::pair<std::shared_ptr<Analyzer::Expr>, std::shared_ptr<Analyzer::Expr>>>
1297  expr_list;
1298  CHECK_EQ(size_t(1), rex_function->size());
1299  const auto operand = translateScalarRex(rex_function->getOperand(0));
1300  const auto& operand_ti = operand->get_type_info();
1301  CHECK(operand_ti.is_number());
1302  const auto zero = makeNumericConstant(operand_ti, 0);
1303  const auto lt_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kLT, kONE, operand, zero);
1304  expr_list.emplace_back(lt_zero, makeNumericConstant(operand_ti, -1));
1305  const auto eq_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kEQ, kONE, operand, zero);
1306  expr_list.emplace_back(eq_zero, makeNumericConstant(operand_ti, 0));
1307  const auto gt_zero = makeExpr<Analyzer::BinOper>(kBOOLEAN, kGT, kONE, operand, zero);
1308  expr_list.emplace_back(gt_zero, makeNumericConstant(operand_ti, 1));
1309  return makeExpr<Analyzer::CaseExpr>(
1310  operand_ti,
1311  false,
1312  expr_list,
1313  makeExpr<Analyzer::Constant>(operand_ti, true, Datum{0}));
1314 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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)
CHECK(cgen_state)
Definition: sqldefs.h:34
Definition: sqldefs.h:69
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 893 of file RelAlgTranslatorGeo.cpp.

References CHECK_EQ, fold_expr(), RexFunctionOperator::getName(), RexOperator::getOperand(), kBOOLEAN, kDOUBLE, kLE, kMULTIPLY, kONE, RexOperator::size(), translateBinaryGeoFunction(), and translateScalarRex().

Referenced by translateFunction().

894  {
895  CHECK_EQ(size_t(3), rex_function->size());
896 
897  auto distance_expr = translateScalarRex(rex_function->getOperand(2));
898  const auto& distance_ti = SQLTypeInfo(kDOUBLE, false);
899  if (distance_expr->get_type_info().get_type() != kDOUBLE) {
900  distance_expr->add_cast(distance_ti);
901  }
902 
903  // Translate the geo distance function call portion
904  const auto geo_distance_expr = translateBinaryGeoFunction(rex_function);
905 
906  if (rex_function->getName() == "ST_DWithin") {
907  auto func_oper = dynamic_cast<Analyzer::FunctionOper*>(geo_distance_expr.get());
908  if (func_oper && func_oper->getName() == "ST_Distance_Point_Point_Squared"sv) {
909  // Point_Point combination will yield geo_distance squared which is faster,
910  // need to compare it with distance squared
911  distance_expr = makeExpr<Analyzer::BinOper>(distance_ti,
912  distance_expr->get_contains_agg(),
913  kMULTIPLY,
914  kONE,
915  distance_expr,
916  distance_expr);
917  distance_expr = fold_expr(distance_expr.get());
918  }
919  }
920 
921  return makeExpr<Analyzer::BinOper>(
922  kBOOLEAN, kLE, kONE, geo_distance_expr, distance_expr);
923 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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:35
Definition: sqldefs.h:69
std::shared_ptr< Analyzer::Expr > translateBinaryGeoFunction(const RexFunctionOperator *) const
const std::string & getName() const
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::translateUnaryGeoFunction ( const RexFunctionOperator rex_function) const
private

Definition at line 564 of file RelAlgTranslatorGeo.cpp.

References CHECK_EQ, func_resolve, SQLTypeInfo::get_comp_param(), SQLTypeInfo::get_compression(), 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, kENCODING_GEOINT, kGEOGRAPHY, kINT, kLINESTRING, kMULTIPOLYGON, kPOINT, kPOLYGON, RexOperator::size(), anonymous_namespace{RelAlgTranslatorGeo.cpp}::suffix(), and translateGeoFunctionArg().

Referenced by translateFunction().

565  {
566  CHECK_EQ(size_t(1), rex_function->size());
567 
568  int32_t lindex = 0;
569  std::string specialized_geofunc{rex_function->getName()};
570 
571  // Geo function calls which do not need the coords col but do need cols associated with
572  // physical coords (e.g. ring_sizes / poly_rings)
573  if (rex_function->getName() == "ST_NRings"sv) {
574  SQLTypeInfo arg_ti;
575  auto geoargs = translateGeoFunctionArg(
576  rex_function->getOperand(0), arg_ti, lindex, false, false, true);
577  if (arg_ti.get_type() == kPOLYGON) {
578  CHECK_EQ(geoargs.size(), 2u);
579  geoargs.erase(geoargs.begin(), geoargs.begin() + 1); // remove the coords
580  return makeExpr<Analyzer::FunctionOper>(
581  rex_function->getType(), specialized_geofunc, geoargs);
582  } else if (arg_ti.get_type() == kMULTIPOLYGON) {
583  CHECK_EQ(geoargs.size(), 3u);
584  geoargs.erase(geoargs.begin(), geoargs.begin() + 1); // remove the coords
585  geoargs.erase(geoargs.begin() + 1, geoargs.end()); // remove the poly_rings
586  return makeExpr<Analyzer::FunctionOper>(
587  rex_function->getType(), specialized_geofunc, geoargs);
588  } else {
589  throw QueryNotSupported(rex_function->getName() +
590  " expects a POLYGON or MULTIPOLYGON");
591  }
592  } else if (rex_function->getName() == "ST_NPoints"sv) {
593  SQLTypeInfo arg_ti;
594  auto geoargs = translateGeoFunctionArg(
595  rex_function->getOperand(0), arg_ti, lindex, false, false, true);
596  geoargs.erase(geoargs.begin() + 1, geoargs.end()); // remove all but coords
597  // Add compression information
598  Datum input_compression;
599  input_compression.intval =
600  (arg_ti.get_compression() == kENCODING_GEOINT && arg_ti.get_comp_param() == 32)
601  ? 1
602  : 0;
603  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
604  return makeExpr<Analyzer::FunctionOper>(
605  rex_function->getType(), specialized_geofunc, geoargs);
606  } else if (func_resolve(rex_function->getName(), "ST_Perimeter"sv, "ST_Area"sv)) {
607  SQLTypeInfo arg_ti;
608  auto geoargs = translateGeoFunctionArg(
609  rex_function->getOperand(0), arg_ti, lindex, false, false, true);
610  if (arg_ti.get_type() != kPOLYGON && arg_ti.get_type() != kMULTIPOLYGON) {
611  throw QueryNotSupported(rex_function->getName() +
612  " expects a POLYGON or MULTIPOLYGON");
613  }
614  specialized_geofunc += suffix(arg_ti.get_type());
615  if (arg_ti.get_subtype() == kGEOGRAPHY && arg_ti.get_output_srid() == 4326) {
616  specialized_geofunc += "_Geodesic"s;
617  }
618  // Add compression information
619  Datum input_compression;
620  input_compression.intval =
621  (arg_ti.get_compression() == kENCODING_GEOINT && arg_ti.get_comp_param() == 32)
622  ? 1
623  : 0;
624  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
625  Datum input_srid;
626  input_srid.intval = arg_ti.get_input_srid();
627  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
628  Datum output_srid;
629  output_srid.intval = arg_ti.get_output_srid();
630  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
631  return makeExpr<Analyzer::FunctionOper>(
632  rex_function->getType(), specialized_geofunc, geoargs);
633  }
634 
635  // Accessors for poly bounds and render group for in-situ poly render queries
636  if (func_resolve(rex_function->getName(),
637  "MapD_GeoPolyBoundsPtr"sv /* deprecated */,
638  "OmniSci_Geo_PolyBoundsPtr"sv)) {
639  SQLTypeInfo arg_ti;
640  // get geo column plus bounds only (not expanded)
641  auto geoargs = translateGeoFunctionArg(
642  rex_function->getOperand(0), arg_ti, lindex, true, false, false);
643  // this function only works on polys
644  if (!IS_GEO_POLY(arg_ti.get_type())) {
645  throw QueryNotSupported(rex_function->getName() +
646  " expects a POLYGON or MULTIPOLYGON");
647  }
648  // only need the bounds argument (last), discard the rest
649  geoargs.erase(geoargs.begin(), geoargs.end() - 1);
650  // done
651  return makeExpr<Analyzer::FunctionOper>(
652  rex_function->getType(), specialized_geofunc, geoargs);
653  } else if (func_resolve(rex_function->getName(),
654  "MapD_GeoPolyRenderGroup"sv /* deprecated */,
655  "OmniSci_Geo_PolyRenderGroup"sv)) {
656  SQLTypeInfo arg_ti;
657  // get geo column plus render_group only (not expanded)
658  auto geoargs = translateGeoFunctionArg(
659  rex_function->getOperand(0), arg_ti, lindex, false, true, false);
660  // this function only works on polys
661  if (!IS_GEO_POLY(arg_ti.get_type())) {
662  throw QueryNotSupported(rex_function->getName() +
663  " expects a POLYGON or MULTIPOLYGON");
664  }
665  // only need the render_group argument (last), discard the rest
666  geoargs.erase(geoargs.begin(), geoargs.end() - 1);
667  // done
668  return makeExpr<Analyzer::FunctionOper>(
669  rex_function->getType(), specialized_geofunc, geoargs);
670  }
671 
672  // All functions below use geo col as reference and expand it as necessary
673  SQLTypeInfo arg_ti;
674  bool with_bounds = true;
675  auto geoargs = translateGeoFunctionArg(
676  rex_function->getOperand(0), arg_ti, lindex, with_bounds, false, false);
677 
678  if (rex_function->getName() == "ST_SRID"sv) {
679  Datum output_srid;
680  output_srid.intval = arg_ti.get_output_srid();
681  return makeExpr<Analyzer::Constant>(kINT, false, output_srid);
682  }
683 
684  if (func_resolve(
685  rex_function->getName(), "ST_XMin"sv, "ST_YMin"sv, "ST_XMax"sv, "ST_YMax"sv)) {
686  // If type has bounds - use them, otherwise look at coords
687  if (arg_ti.has_bounds()) {
688  if (lindex != 0) {
689  throw QueryNotSupported(rex_function->getName() +
690  " doesn't support indexed LINESTRINGs");
691  }
692  // Only need the bounds argument, discard the rest
693  geoargs.erase(geoargs.begin(), geoargs.end() - 1);
694 
695  // Supply srids too - transformed geo would have a transformed bounding box
696  Datum input_srid;
697  input_srid.intval = arg_ti.get_input_srid();
698  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
699  Datum output_srid;
700  output_srid.intval = arg_ti.get_output_srid();
701  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
702 
703  specialized_geofunc += "_Bounds"s;
704  return makeExpr<Analyzer::FunctionOper>(
705  rex_function->getType(), specialized_geofunc, geoargs);
706  }
707  }
708 
709  // All geo function calls translated below only need the coords, extras e.g. ring_sizes
710  // are dropped. Specialize for other/new functions if needed.
711  geoargs.erase(geoargs.begin() + 1, geoargs.end());
712 
713  if (func_resolve(rex_function->getName(), "ST_X"sv, "ST_Y"sv)) {
714  if (arg_ti.get_type() == kLINESTRING) {
715  if (lindex == 0) {
716  throw QueryNotSupported(
717  rex_function->getName() +
718  " expects a POINT, use LINESTRING accessor, e.g. ST_POINTN");
719  }
720  Datum index;
721  index.intval = lindex;
722  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, index));
723  } else if (arg_ti.get_type() != kPOINT) {
724  throw QueryNotSupported(rex_function->getName() + " expects a POINT");
725  }
726  specialized_geofunc += suffix(arg_ti.get_type());
727  } else if (rex_function->getName() == "ST_Length"sv) {
728  if (arg_ti.get_type() != kLINESTRING || lindex != 0) {
729  throw QueryNotSupported(rex_function->getName() + " expects unindexed LINESTRING");
730  }
731  specialized_geofunc += suffix(arg_ti.get_type());
732  if (arg_ti.get_subtype() == kGEOGRAPHY && arg_ti.get_output_srid() == 4326) {
733  specialized_geofunc += "_Geodesic"s;
734  }
735  }
736 
737  // Add input compression mode and SRID args to enable on-the-fly
738  // decompression/transforms
739  Datum input_compression;
740  input_compression.intval =
741  (arg_ti.get_compression() == kENCODING_GEOINT && arg_ti.get_comp_param() == 32) ? 1
742  : 0;
743  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
744  Datum input_srid;
745  input_srid.intval = arg_ti.get_input_srid();
746  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
747 
748  // Add output SRID arg to enable on-the-fly transforms
749  Datum output_srid;
750  output_srid.intval = arg_ti.get_output_srid();
751  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
752 
753  return makeExpr<Analyzer::FunctionOper>(
754  rex_function->getType(), specialized_geofunc, geoargs);
755 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:249
#define CHECK_EQ(x, y)
Definition: Logger.h:205
auto func_resolve
const SQLTypeInfo & getType() const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:248
int32_t intval
Definition: sqltypes.h:126
bool has_bounds() const
Definition: sqltypes.h:317
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:256
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:257
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:252
Definition: sqltypes.h:46
const std::string & getName() 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
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:254
#define IS_GEO_POLY(T)
Definition: sqltypes.h:167

+ 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 941 of file RelAlgTranslator.cpp.

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

Referenced by translateFunction().

942  {
943  CHECK(rex_function->size() == 1);
944  const auto arg = translateScalarRex(rex_function->getOperand(0));
945  return makeExpr<Analyzer::LikelihoodExpr>(arg, 0.0625);
946 }
std::shared_ptr< Analyzer::Expr > translateScalarRex(const RexScalar *rex) const
size_t size() const
const RexScalar * getOperand(const size_t idx) const
CHECK(cgen_state)

+ 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 393 of file RelAlgTranslator.cpp.

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

Referenced by translateOper().

394  {
395  CHECK_EQ(size_t(1), rex_operator->size());
396  const auto operand_expr = translateScalarRex(rex_operator->getOperand(0));
397  const auto sql_op = rex_operator->getOperator();
398  switch (sql_op) {
399  case kCAST: {
400  const auto& target_ti = rex_operator->getType();
401  CHECK_NE(kNULLT, target_ti.get_type());
402  const auto& operand_ti = operand_expr->get_type_info();
403  if (operand_ti.is_string() && target_ti.is_string()) {
404  return operand_expr;
405  }
406  if (target_ti.is_time() ||
407  operand_ti
408  .is_string()) { // TODO(alex): check and unify with the rest of the cases
409  // Do not propogate encoding on small dates
410  return target_ti.is_date_in_days()
411  ? operand_expr->add_cast(SQLTypeInfo(kDATE, false))
412  : operand_expr->add_cast(target_ti);
413  }
414  if (!operand_ti.is_string() && target_ti.is_string()) {
415  return operand_expr->add_cast(target_ti);
416  }
417 
418  return std::make_shared<Analyzer::UOper>(target_ti, false, sql_op, operand_expr);
419  }
420  case kNOT:
421  case kISNULL: {
422  return std::make_shared<Analyzer::UOper>(kBOOLEAN, sql_op, operand_expr);
423  }
424  case kISNOTNULL: {
425  auto is_null = std::make_shared<Analyzer::UOper>(kBOOLEAN, kISNULL, operand_expr);
426  return std::make_shared<Analyzer::UOper>(kBOOLEAN, kNOT, is_null);
427  }
428  case kMINUS: {
429  const auto& ti = operand_expr->get_type_info();
430  return std::make_shared<Analyzer::UOper>(ti, false, kUMINUS, operand_expr);
431  }
432  case kUNNEST: {
433  const auto& ti = operand_expr->get_type_info();
434  CHECK(ti.is_array());
435  return makeExpr<Analyzer::UOper>(ti.get_elem_type(), false, kUNNEST, operand_expr);
436  }
437  default:
438  CHECK(false);
439  }
440  return nullptr;
441 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
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:49
SQLOps getOperator() const
CHECK(cgen_state)
#define CHECK_NE(x, y)
Definition: Logger.h:206
Definition: sqltypes.h:54
Definition: sqldefs.h:40
bool is_null(const T &v, const SQLTypeInfo &t)
Definition: sqldefs.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< Analyzer::Expr > RelAlgTranslator::translateWindowFunction ( const RexWindowFunctionOperator rex_window_function) const
private

Definition at line 1629 of file RelAlgTranslator.cpp.

References run_benchmark_import::args, CHECK_GE, RexWindowFunctionOperator::getCollation(), RexWindowFunctionOperator::getKind(), RexWindowFunctionOperator::getLowerBound(), RexOperator::getOperand(), RexWindowFunctionOperator::getOrderKeys(), RexWindowFunctionOperator::getPartitionKeys(), RexOperator::getType(), RexWindowFunctionOperator::isRows(), ROW_NUMBER, RexOperator::size(), anonymous_namespace{RelAlgTranslator.cpp}::supported_lower_bound(), anonymous_namespace{RelAlgTranslator.cpp}::supported_upper_bound(), anonymous_namespace{RelAlgTranslator.cpp}::translate_collation(), translateScalarRex(), and window_function_is_value().

Referenced by translateScalarRex().

1630  {
1631  if (!supported_lower_bound(rex_window_function->getLowerBound()) ||
1632  !supported_upper_bound(rex_window_function) ||
1633  ((rex_window_function->getKind() == SqlWindowFunctionKind::ROW_NUMBER) !=
1634  rex_window_function->isRows())) {
1635  throw std::runtime_error("Frame specification not supported");
1636  }
1637  std::vector<std::shared_ptr<Analyzer::Expr>> args;
1638  for (size_t i = 0; i < rex_window_function->size(); ++i) {
1639  args.push_back(translateScalarRex(rex_window_function->getOperand(i)));
1640  }
1641  std::vector<std::shared_ptr<Analyzer::Expr>> partition_keys;
1642  for (const auto& partition_key : rex_window_function->getPartitionKeys()) {
1643  partition_keys.push_back(translateScalarRex(partition_key.get()));
1644  }
1645  std::vector<std::shared_ptr<Analyzer::Expr>> order_keys;
1646  for (const auto& order_key : rex_window_function->getOrderKeys()) {
1647  order_keys.push_back(translateScalarRex(order_key.get()));
1648  }
1649  auto ti = rex_window_function->getType();
1650  if (window_function_is_value(rex_window_function->getKind())) {
1651  CHECK_GE(args.size(), 1u);
1652  ti = args.front()->get_type_info();
1653  }
1654  return makeExpr<Analyzer::WindowFunction>(
1655  ti,
1656  rex_window_function->getKind(),
1657  args,
1658  partition_keys,
1659  order_keys,
1660  translate_collation(rex_window_function->getCollation()));
1661 }
bool supported_lower_bound(const RexWindowFunctionOperator::RexWindowBound &window_bound)
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
const std::vector< SortField > & getCollation() const
#define CHECK_GE(x, y)
Definition: Logger.h:210
bool window_function_is_value(const SqlWindowFunctionKind kind)
Definition: WindowContext.h:27
std::vector< Analyzer::OrderEntry > translate_collation(const std::vector< SortField > &sort_fields)
const ConstRexScalarPtrVector & getPartitionKeys() const
const RexWindowBound & getLowerBound() const
SqlWindowFunctionKind getKind() const
bool supported_upper_bound(const RexWindowFunctionOperator *rex_window_function)
const ConstRexScalarPtrVector & getOrderKeys() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

const Catalog_Namespace::Catalog& RelAlgTranslator::cat_
private

Definition at line 173 of file RelAlgTranslator.h.

Referenced by getInIntegerSetExpr(), translateGeoColumn(), and translateInput().

const Executor* RelAlgTranslator::executor_
private

Definition at line 174 of file RelAlgTranslator.h.

Referenced by getInIntegerSetExpr().

QueryFeatureDescriptor& RelAlgTranslator::feature_stash_
private

Definition at line 179 of file RelAlgTranslator.h.

Referenced by translateArrayFunction().

const std::unordered_map<const RelAlgNode*, int> RelAlgTranslator::input_to_nest_level_
private

Definition at line 175 of file RelAlgTranslator.h.

Referenced by translateGeoColumn(), and translateInput().

const std::vector<JoinType> RelAlgTranslator::join_types_
private

Definition at line 176 of file RelAlgTranslator.h.

Referenced by translateInput().

const bool RelAlgTranslator::just_explain_
private

Definition at line 178 of file RelAlgTranslator.h.

Referenced by translateInOper(), and translateScalarSubquery().

time_t RelAlgTranslator::now_
private

Definition at line 177 of file RelAlgTranslator.h.

Referenced by translateNow().


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