OmniSciDB  1dac507f6e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CalciteAdapter.cpp File Reference
#include "CalciteAdapter.h"
#include "CalciteDeserializerUtils.h"
#include "DateTimeTranslator.h"
#include "../Parser/ParserNode.h"
#include "../Shared/StringTransform.h"
#include <rapidjson/document.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/regex.hpp>
#include <set>
#include <unordered_map>
#include <unordered_set>
+ Include dependency graph for CalciteAdapter.cpp:

Go to the source code of this file.

Classes

class  anonymous_namespace{CalciteAdapter.cpp}::CalciteAdapter
 
struct  anonymous_namespace{CalciteAdapter.cpp}::CalciteAdapter::ColNames
 
struct  anonymous_namespace{CalciteAdapter.cpp}::LogicalSortInfo
 

Namespaces

 anonymous_namespace{CalciteAdapter.cpp}
 

Functions

ssize_t anonymous_namespace{CalciteAdapter.cpp}::get_agg_operand_idx (const rapidjson::Value &expr)
 
std::tuple< const
rapidjson::Value
*, SQLTypeInfo, SQLTypeInfo
anonymous_namespace{CalciteAdapter.cpp}::parse_literal (const rapidjson::Value &expr)
 
std::shared_ptr< Analyzer::Expranonymous_namespace{CalciteAdapter.cpp}::set_transient_dict (const std::shared_ptr< Analyzer::Expr > expr)
 
void anonymous_namespace{CalciteAdapter.cpp}::reproject_target_entries (std::vector< std::shared_ptr< Analyzer::TargetEntry >> &agg_targets, const std::vector< size_t > &result_proj_indices, const rapidjson::Value &fields)
 
LogicalSortInfo anonymous_namespace{CalciteAdapter.cpp}::get_logical_sort_info (const rapidjson::Value &rels)
 
Planner::Scananonymous_namespace{CalciteAdapter.cpp}::get_scan_plan (const TableDescriptor *td, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &scan_targets, std::list< std::shared_ptr< Analyzer::Expr >> &q, std::list< std::shared_ptr< Analyzer::Expr >> &sq, CalciteAdapter &calcite_adapter)
 
Planner::Plananonymous_namespace{CalciteAdapter.cpp}::get_agg_plan (const TableDescriptor *td, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &scan_targets, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &agg_targets, const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, std::list< std::shared_ptr< Analyzer::Expr >> &q, std::list< std::shared_ptr< Analyzer::Expr >> &sq, CalciteAdapter &calcite_adapter)
 
Planner::Plananonymous_namespace{CalciteAdapter.cpp}::get_sort_plan (Planner::Plan *plan, const rapidjson::Value &rels, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &scan_targets, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &agg_targets)
 
std::vector< size_t > anonymous_namespace{CalciteAdapter.cpp}::collect_reproject_indices (const rapidjson::Value &exprs)
 
std::vector< std::shared_ptr
< Analyzer::TargetEntry > > 
anonymous_namespace{CalciteAdapter.cpp}::get_input_targets (const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets, const rapidjson::Value &exprs, const rapidjson::Value &fields, CalciteAdapter &calcite_adapter)
 
bool anonymous_namespace{CalciteAdapter.cpp}::needs_result_plan (const rapidjson::Value &exprs)
 
std::vector< std::shared_ptr
< Analyzer::TargetEntry > > 
anonymous_namespace{CalciteAdapter.cpp}::build_var_refs (const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets)
 
std::vector< std::shared_ptr
< Analyzer::TargetEntry > > 
anonymous_namespace{CalciteAdapter.cpp}::build_result_plan_targets (const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets, const rapidjson::Value &exprs, const rapidjson::Value &fields, CalciteAdapter &calcite_adapter)
 
bool anonymous_namespace{CalciteAdapter.cpp}::targets_are_refs (const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets)
 
std::vector< std::shared_ptr
< Analyzer::TargetEntry > > 
anonymous_namespace{CalciteAdapter.cpp}::handle_logical_project (std::vector< std::shared_ptr< Analyzer::TargetEntry >> &child_plan_targets, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets, const rapidjson::Value &logical_project, CalciteAdapter &calcite_adapter)
 
std::vector< std::shared_ptr
< Analyzer::TargetEntry > > 
anonymous_namespace{CalciteAdapter.cpp}::handle_logical_aggregate (const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets, std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, const rapidjson::Value &logical_aggregate, CalciteAdapter &calcite_adapter)
 
void anonymous_namespace{CalciteAdapter.cpp}::add_quals (const std::shared_ptr< Analyzer::Expr > qual_expr, std::list< std::shared_ptr< Analyzer::Expr >> &simple_quals, std::list< std::shared_ptr< Analyzer::Expr >> &quals)
 
void anonymous_namespace{CalciteAdapter.cpp}::collect_used_columns (std::vector< std::shared_ptr< Analyzer::ColumnVar >> &used_cols, const std::shared_ptr< Analyzer::Expr > expr)
 
std::unordered_set< int > anonymous_namespace{CalciteAdapter.cpp}::get_used_table_ids (const std::vector< std::shared_ptr< Analyzer::ColumnVar >> &used_cols)
 
void anonymous_namespace{CalciteAdapter.cpp}::separate_join_quals (std::unordered_map< int, std::list< std::shared_ptr< Analyzer::Expr >>> &quals, std::list< std::shared_ptr< Analyzer::Expr >> &join_quals, const std::list< std::shared_ptr< Analyzer::Expr >> &all_quals)
 
const std::string anonymous_namespace{CalciteAdapter.cpp}::get_op_name (const rapidjson::Value &obj)
 
bool anonymous_namespace{CalciteAdapter.cpp}::match_compound_seq (rapidjson::Value::ConstValueIterator &rels_it, const rapidjson::Value::ConstValueIterator rels_end)
 
bool anonymous_namespace{CalciteAdapter.cpp}::match_filter_project_seq (rapidjson::Value::ConstValueIterator &rels_it, const rapidjson::Value::ConstValueIterator rels_end)
 
bool anonymous_namespace{CalciteAdapter.cpp}::match_sort_seq (rapidjson::Value::ConstValueIterator &rels_it, const rapidjson::Value::ConstValueIterator rels_end)
 
bool anonymous_namespace{CalciteAdapter.cpp}::query_is_supported (const rapidjson::Value &rels)
 
Planner::RootPlantranslate_query (const std::string &query, const Catalog_Namespace::Catalog &cat)
 
std::string anonymous_namespace{CalciteAdapter.cpp}::pg_shim_impl (const std::string &query)
 
std::string pg_shim (const std::string &query)
 

Function Documentation

std::string pg_shim ( const std::string &  query)

Definition at line 1468 of file CalciteAdapter.cpp.

References LOG, anonymous_namespace{CalciteAdapter.cpp}::pg_shim_impl(), and logger::WARNING.

Referenced by Parser::CreateViewStmt::execute(), Parser::getResultSet(), MapDHandler::parse_to_ra(), QueryRunner::QueryRunner::parsePlanCalcite(), Parser::InsertIntoTableAsSelectStmt::LocalConnector::query(), QueryRunner::anonymous_namespace{QueryRunner.cpp}::run_select_query_with_filter_push_down(), and QueryRunner::QueryRunner::runSelectQuery().

1468  {
1469  try {
1470  return pg_shim_impl(query);
1471  } catch (const std::exception& e) {
1472  LOG(WARNING) << "Error applying shim: " << e.what() << "\nContinuing query parse...";
1473  // boost::regex throws an exception about the complexity of matching when
1474  // the wrong type of quotes are used or they're mismatched. Let the query
1475  // through unmodified, the parser will throw a much more informative error.
1476  }
1477  return query;
1478 }
#define LOG(tag)
Definition: Logger.h:185
std::string pg_shim_impl(const std::string &query)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Planner::RootPlan* translate_query ( const std::string &  query,
const Catalog_Namespace::Catalog cat 
)

Definition at line 1150 of file CalciteAdapter.cpp.

References anonymous_namespace{CalciteAdapter.cpp}::add_quals(), anonymous_namespace{CalciteAdapter.cpp}::build_var_refs(), CHECK(), anonymous_namespace{CalciteAdapter.cpp}::handle_logical_aggregate(), anonymous_namespace{CalciteAdapter.cpp}::handle_logical_project(), and anonymous_namespace{CalciteAdapter.cpp}::query_is_supported().

Referenced by QueryRunner::QueryRunner::parsePlanCalcite().

1151  {
1152  rapidjson::Document query_ast;
1153  query_ast.Parse(query.c_str());
1154  CHECK(!query_ast.HasParseError());
1155  CHECK(query_ast.IsObject());
1156  const auto& rels = query_ast["rels"];
1157  if (!query_is_supported(rels)) {
1158  throw std::runtime_error("This query is not supported yet");
1159  }
1160  CHECK(rels.IsArray());
1161  CalciteAdapter calcite_adapter(cat, rels);
1162  std::list<std::shared_ptr<Analyzer::Expr>> quals;
1163  std::list<std::shared_ptr<Analyzer::Expr>> simple_quals;
1164  std::list<std::shared_ptr<Analyzer::Expr>> result_quals;
1165  std::list<std::shared_ptr<Analyzer::Expr>> all_join_simple_quals;
1166  std::list<std::shared_ptr<Analyzer::Expr>> all_join_quals;
1167  std::vector<std::shared_ptr<Analyzer::TargetEntry>> child_res_targets;
1168  std::vector<std::shared_ptr<Analyzer::TargetEntry>> res_targets;
1169  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1170  bool is_agg_plan{false};
1171  bool is_join{false};
1172  for (auto rels_it = rels.Begin(); rels_it != rels.End(); ++rels_it) {
1173  const auto& crt_node = *rels_it;
1174  CHECK(crt_node.IsObject());
1175  const auto rel_op_it = crt_node.FindMember("relOp");
1176  CHECK(rel_op_it != crt_node.MemberEnd());
1177  CHECK(rel_op_it->value.IsString());
1178  if (rel_op_it->value.GetString() == std::string("EnumerableTableScan") ||
1179  rel_op_it->value.GetString() == std::string("LogicalSort")) {
1180  continue;
1181  }
1182  if (rel_op_it->value.GetString() == std::string("LogicalProject")) {
1183  res_targets = handle_logical_project(
1184  child_res_targets, res_targets, crt_node, calcite_adapter);
1185  } else if (rel_op_it->value.GetString() == std::string("LogicalAggregate")) {
1186  is_agg_plan = true;
1187  CHECK(!res_targets.empty());
1188  res_targets =
1189  handle_logical_aggregate(res_targets, groupby_exprs, crt_node, calcite_adapter);
1190  } else if (rel_op_it->value.GetString() == std::string("LogicalFilter")) {
1191  if (res_targets.empty()) {
1192  if (is_join) {
1193  add_quals(calcite_adapter.getExprFromNode(crt_node["condition"], {}),
1194  all_join_simple_quals,
1195  all_join_quals);
1196  } else {
1197  add_quals(calcite_adapter.getExprFromNode(crt_node["condition"], {}),
1198  simple_quals,
1199  quals);
1200  }
1201  } else {
1202  child_res_targets = res_targets;
1203  res_targets = build_var_refs(res_targets);
1204  add_quals(calcite_adapter.getExprFromNode(crt_node["condition"], res_targets),
1205  result_quals,
1206  result_quals);
1207  }
1208  } else if (rel_op_it->value.GetString() == std::string("LogicalJoin")) {
1209  const auto condition = std::dynamic_pointer_cast<Analyzer::Constant>(
1210  calcite_adapter.getExprFromNode(crt_node["condition"], {}));
1211  if (!condition) {
1212  throw std::runtime_error("Unsupported join condition");
1213  }
1214  const auto condition_ti = condition->get_type_info();
1215  CHECK(condition_ti.is_boolean());
1216  if (crt_node["joinType"].GetString() != std::string("inner")) {
1217  throw std::runtime_error("Only inner joins supported for now");
1218  }
1219  // TODO(alex): use the information in this node?
1220  is_join = true;
1221  } else {
1222  throw std::runtime_error(std::string("Node ") + rel_op_it->value.GetString() +
1223  " not supported yet");
1224  }
1225  }
1226  const auto tds = calcite_adapter.getTableDescriptors();
1227  if (is_join) {
1228  CHECK_EQ(size_t(2), tds.size());
1229  } else {
1230  CHECK_EQ(size_t(1), tds.size());
1231  }
1232  CHECK(!res_targets.empty());
1233  Planner::Plan* plan{nullptr};
1234  if (is_join) {
1235  std::unordered_map<int, std::list<std::shared_ptr<Analyzer::Expr>>> scan_quals;
1236  std::list<std::shared_ptr<Analyzer::Expr>> join_quals;
1237  separate_join_quals(scan_quals, join_quals, all_join_quals);
1238  std::unordered_map<int, std::list<std::shared_ptr<Analyzer::Expr>>> scan_simple_quals;
1239  std::list<std::shared_ptr<Analyzer::Expr>> join_simple_quals;
1240  separate_join_quals(scan_simple_quals, join_simple_quals, all_join_simple_quals);
1241  CHECK_LE(scan_quals.size(), size_t(2));
1242  CHECK_LE(scan_simple_quals.size(), size_t(2));
1243  const int outer_tid = tds[0]->tableId;
1244  const int inner_tid = tds[1]->tableId;
1245  auto outer_plan = get_agg_plan(tds[0],
1246  {},
1247  {},
1248  groupby_exprs,
1249  scan_quals[outer_tid],
1250  scan_simple_quals[outer_tid],
1251  calcite_adapter);
1252  auto inner_plan = get_agg_plan(tds[1],
1253  {},
1254  {},
1255  groupby_exprs,
1256  scan_quals[inner_tid],
1257  scan_simple_quals[inner_tid],
1258  calcite_adapter);
1259  if (child_res_targets.empty()) {
1260  if (is_agg_plan) {
1261  plan = new Planner::Join({}, join_quals, 0, outer_plan, inner_plan);
1262  plan = new Planner::AggPlan(res_targets, 0., plan, groupby_exprs);
1263  } else {
1264  plan = new Planner::Join(res_targets, join_quals, 0, outer_plan, inner_plan);
1265  }
1266  } else {
1267  if (is_agg_plan) {
1268  plan = new Planner::Join({}, join_quals, 0, outer_plan, inner_plan);
1269  plan = new Planner::AggPlan(child_res_targets, 0., plan, groupby_exprs);
1270  } else {
1271  plan =
1272  new Planner::Join(child_res_targets, join_quals, 0, outer_plan, inner_plan);
1273  }
1274  plan = new Planner::Result(res_targets, result_quals, 0, plan, {});
1275  }
1276  } else if (child_res_targets.empty()) {
1277  std::vector<std::shared_ptr<Analyzer::TargetEntry>> agg_targets{
1278  is_agg_plan ? res_targets
1279  : std::vector<std::shared_ptr<Analyzer::TargetEntry>>{}};
1280  std::vector<std::shared_ptr<Analyzer::TargetEntry>> scan_targets{
1281  is_agg_plan ? std::vector<std::shared_ptr<Analyzer::TargetEntry>>{}
1282  : res_targets};
1283  plan = get_agg_plan(tds[0],
1284  scan_targets,
1285  agg_targets,
1286  groupby_exprs,
1287  quals,
1288  simple_quals,
1289  calcite_adapter);
1290  } else {
1291  std::vector<std::shared_ptr<Analyzer::TargetEntry>> agg_targets{
1292  is_agg_plan ? child_res_targets
1293  : std::vector<std::shared_ptr<Analyzer::TargetEntry>>{}};
1294  std::vector<std::shared_ptr<Analyzer::TargetEntry>> scan_targets{
1295  is_agg_plan ? std::vector<std::shared_ptr<Analyzer::TargetEntry>>{}
1296  : child_res_targets};
1297  plan = get_agg_plan(tds[0],
1298  scan_targets,
1299  agg_targets,
1300  groupby_exprs,
1301  quals,
1302  simple_quals,
1303  calcite_adapter);
1304  plan = new Planner::Result(res_targets, result_quals, 0, plan, {});
1305  }
1306  CHECK(plan);
1307  const auto logical_sort_info = get_logical_sort_info(rels);
1308  plan = get_sort_plan(plan, rels, {}, res_targets);
1309  return new Planner::RootPlan(plan,
1310  kSELECT,
1311  tds[0]->tableId,
1312  {},
1313  cat,
1314  logical_sort_info.limit,
1315  logical_sort_info.offset);
1316 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
void add_quals(const std::shared_ptr< Analyzer::Expr > qual_expr, std::list< std::shared_ptr< Analyzer::Expr >> &simple_quals, std::list< std::shared_ptr< Analyzer::Expr >> &quals)
std::vector< std::shared_ptr< Analyzer::TargetEntry > > build_var_refs(const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets)
std::vector< std::shared_ptr< Analyzer::TargetEntry > > handle_logical_aggregate(const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets, std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, const rapidjson::Value &logical_aggregate, CalciteAdapter &calcite_adapter)
LogicalSortInfo get_logical_sort_info(const rapidjson::Value &rels)
CHECK(cgen_state)
std::vector< std::shared_ptr< Analyzer::TargetEntry > > handle_logical_project(std::vector< std::shared_ptr< Analyzer::TargetEntry >> &child_plan_targets, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &in_targets, const rapidjson::Value &logical_project, CalciteAdapter &calcite_adapter)
Planner::Plan * get_agg_plan(const TableDescriptor *td, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &scan_targets, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &agg_targets, const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, std::list< std::shared_ptr< Analyzer::Expr >> &q, std::list< std::shared_ptr< Analyzer::Expr >> &sq, CalciteAdapter &calcite_adapter)
void separate_join_quals(std::unordered_map< int, std::list< std::shared_ptr< Analyzer::Expr >>> &quals, std::list< std::shared_ptr< Analyzer::Expr >> &join_quals, const std::list< std::shared_ptr< Analyzer::Expr >> &all_quals)
#define CHECK_LE(x, y)
Definition: Logger.h:201
Planner::Plan * get_sort_plan(Planner::Plan *plan, const rapidjson::Value &rels, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &scan_targets, const std::vector< std::shared_ptr< Analyzer::TargetEntry >> &agg_targets)
bool query_is_supported(const rapidjson::Value &rels)

+ Here is the call graph for this function:

+ Here is the caller graph for this function: