OmniSciDB  085a039ca4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QueryHint.h
Go to the documentation of this file.
1 /*
2  * Copyright 2020 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef OMNISCI_QUERYHINT_H
18 #define OMNISCI_QUERYHINT_H
19 
20 #include <algorithm>
21 #include <optional>
22 
23 #include <boost/algorithm/string.hpp>
24 
26 
27 // we expect query hint enum val starts with zero,
28 // and let remaining enum value to be auto-incremented
29 enum QueryHint {
30  kCpuMode = 0,
40  kHintCount, // should be at the last elem before INVALID enum value to count #
41  // supported hints correctly
42  kInvalidHint // this should be the last elem of this enum
43 };
44 
45 static const std::unordered_map<std::string, QueryHint> SupportedQueryHints = {
46  {"cpu_mode", QueryHint::kCpuMode},
47  {"columnar_output", QueryHint::kColumnarOutput},
48  {"rowwise_output", QueryHint::kRowwiseOutput},
49  {"overlaps_bucket_threshold", QueryHint::kOverlapsBucketThreshold},
50  {"overlaps_max_size", QueryHint::kOverlapsMaxSize},
51  {"overlaps_allow_gpu_build", QueryHint::kOverlapsAllowGpuBuild},
52  {"overlaps_no_cache", QueryHint::kOverlapsNoCache},
53  {"overlaps_keys_per_bin", QueryHint::kOverlapsKeysPerBin},
54  {"keep_result", QueryHint::kKeepResult},
55  {"keep_table_function_result", QueryHint::kKeepTableFuncResult}};
56 
59  std::string hint_name;
60 
61  HintIdentifier(bool global_hint, const std::string& hint_name)
62  : global_hint(global_hint), hint_name(hint_name){};
63 };
64 
66  // this class represents parsed query hint's specification
67  // our query AST analyzer translates query hint string to understandable form which we
68  // called "ExplainedQueryHint"
69  public:
71  bool global_hint,
72  bool is_marker,
73  bool has_kv_type_options)
74  : hint_(hint)
75  , global_hint_(global_hint)
76  , is_marker_(is_marker)
77  , has_kv_type_options_(has_kv_type_options) {}
78 
80  bool global_hint,
81  bool is_marker,
82  bool has_kv_type_options,
83  std::vector<std::string>& list_options)
84  : hint_(hint)
85  , global_hint_(global_hint)
86  , is_marker_(is_marker)
87  , has_kv_type_options_(has_kv_type_options)
88  , list_options_(std::move(list_options)) {}
89 
91  bool global_hint,
92  bool is_marker,
93  bool has_kv_type_options,
94  std::unordered_map<std::string, std::string>& kv_options)
95  : hint_(hint)
96  , global_hint_(global_hint)
97  , is_marker_(is_marker)
98  , has_kv_type_options_(has_kv_type_options)
99  , kv_options_(std::move(kv_options)) {}
100 
101  void setListOptions(std::vector<std::string>& list_options) {
102  list_options_ = list_options;
103  }
104 
105  void setKVOptions(std::unordered_map<std::string, std::string>& kv_options) {
106  kv_options_ = kv_options;
107  }
108 
109  void setInheritPaths(std::vector<int>& interit_paths) {
110  inherit_paths_ = interit_paths;
111  }
112 
113  const std::vector<std::string>& getListOptions() { return list_options_; }
114 
115  const std::vector<int>& getInteritPath() { return inherit_paths_; }
116 
117  const std::unordered_map<std::string, std::string>& getKVOptions() {
118  return kv_options_;
119  }
120 
121  const QueryHint getHint() const { return hint_; }
122 
123  bool isGlobalHint() const { return global_hint_; }
124 
125  bool hasOptions() const { return is_marker_; }
126 
127  bool hasKvOptions() const { return has_kv_type_options_; }
128 
129  private:
131  // Set true if this hint affects globally
132  // Otherwise it just affects the node which this hint is included (aka table hint)
134  // set true if this has no extra options (neither list_options nor kv_options)
136  // Set true if it is not a marker and has key-value type options
137  // Otherwise (it is not a marker but has list type options), we set this be false
139  std::vector<int> inherit_paths_; // currently not used
140  std::vector<std::string> list_options_;
141  std::unordered_map<std::string, std::string> kv_options_;
142 };
143 
145  // for each query hint, we first translate the raw query hint info
146  // to understandable form called "ExplainedQueryHint"
147  // and we get all necessary info from it and organize it into "RegisteredQueryHint"
148  // so by using "RegisteredQueryHint", we can know and access which query hint is
149  // registered and its detailed info such as the hint's parameter values given by user
151  : cpu_mode(false)
154  , overlaps_bucket_threshold(std::numeric_limits<double>::max())
160 
162  CHECK_EQ(registered_hint.size(), global_hints.registered_hint.size());
163  // apply registered global hint to the local hint if necessary
164  // we prioritize global hint when both side of hints are enabled simultaneously
165  RegisteredQueryHint updated_query_hints(*this);
166 
167  int num_hints = static_cast<int>(QueryHint::kHintCount);
168  for (int i = 0; i < num_hints; ++i) {
169  if (global_hints.registered_hint.at(i)) {
170  updated_query_hints.registered_hint.at(i) = global_hints.registered_hint[i];
171  switch (i) {
172  case static_cast<int>(QueryHint::kCpuMode): {
173  updated_query_hints.cpu_mode = true;
174  break;
175  }
176  case static_cast<int>(QueryHint::kColumnarOutput): {
177  updated_query_hints.columnar_output = true;
178  break;
179  }
180  case static_cast<int>(QueryHint::kRowwiseOutput): {
181  updated_query_hints.rowwise_output = true;
182  break;
183  }
184  case static_cast<int>(QueryHint::kOverlapsBucketThreshold): {
185  updated_query_hints.overlaps_bucket_threshold =
186  global_hints.overlaps_bucket_threshold;
187  break;
188  }
189  case static_cast<int>(QueryHint::kOverlapsMaxSize): {
190  updated_query_hints.overlaps_max_size = global_hints.overlaps_max_size;
191  break;
192  }
193  case static_cast<int>(QueryHint::kOverlapsAllowGpuBuild): {
194  updated_query_hints.overlaps_allow_gpu_build = true;
195  break;
196  }
197  case static_cast<int>(QueryHint::kOverlapsNoCache): {
198  updated_query_hints.overlaps_no_cache = true;
199  break;
200  }
201  case static_cast<int>(QueryHint::kOverlapsKeysPerBin): {
202  updated_query_hints.overlaps_keys_per_bin =
203  global_hints.overlaps_keys_per_bin;
204  break;
205  }
206  case static_cast<int>(QueryHint::kKeepResult): {
207  updated_query_hints.keep_result = global_hints.keep_result;
208  break;
209  }
210  case static_cast<int>(QueryHint::kKeepTableFuncResult): {
211  updated_query_hints.keep_table_function_result =
212  global_hints.keep_table_function_result;
213  break;
214  }
215  }
216  }
217  }
218  return updated_query_hints;
219  }
220 
221  // general query execution
222  bool cpu_mode;
227 
228  // overlaps hash join
229  double overlaps_bucket_threshold; // defined in "OverlapsJoinHashTable.h"
234 
235  std::vector<bool> registered_hint;
236 
238 
239  public:
240  static QueryHint translateQueryHint(const std::string& hint_name) {
241  const auto lowered_hint_name = boost::algorithm::to_lower_copy(hint_name);
242  auto it = SupportedQueryHints.find(lowered_hint_name);
243  return it == SupportedQueryHints.end() ? QueryHint::kInvalidHint : it->second;
244  }
245 
246  bool isAnyQueryHintDelivered() const {
247  const auto identity = [](const bool b) { return b; };
248  return std::any_of(registered_hint.begin(), registered_hint.end(), identity);
249  }
250 
251  void registerHint(const QueryHint hint) {
252  const auto hint_class = static_cast<int>(hint);
253  registered_hint.at(hint_class) = true;
254  }
255 
256  bool isHintRegistered(const QueryHint hint) const {
257  const auto hint_class = static_cast<int>(hint);
258  return registered_hint.at(hint_class);
259  }
260 };
261 
262 // a map from hint_name to its detailed info
263 using Hints = std::unordered_map<QueryHint, ExplainedQueryHint>;
264 
265 #endif // OMNISCI_QUERYHINT_H
std::unordered_map< std::string, std::string > kv_options_
Definition: QueryHint.h:141
#define CHECK_EQ(x, y)
Definition: Logger.h:231
bool isGlobalHint() const
Definition: QueryHint.h:123
const std::vector< int > & getInteritPath()
Definition: QueryHint.h:115
bool overlaps_allow_gpu_build
Definition: QueryHint.h:231
void setListOptions(std::vector< std::string > &list_options)
Definition: QueryHint.h:101
double overlaps_keys_per_bin
Definition: QueryHint.h:233
ExplainedQueryHint(QueryHint hint, bool global_hint, bool is_marker, bool has_kv_type_options)
Definition: QueryHint.h:70
std::vector< bool > registered_hint
Definition: QueryHint.h:235
void setKVOptions(std::unordered_map< std::string, std::string > &kv_options)
Definition: QueryHint.h:105
ExplainedQueryHint(QueryHint hint, bool global_hint, bool is_marker, bool has_kv_type_options, std::vector< std::string > &list_options)
Definition: QueryHint.h:79
bool hasKvOptions() const
Definition: QueryHint.h:127
bool keep_table_function_result
Definition: QueryHint.h:226
static const std::unordered_map< std::string, QueryHint > SupportedQueryHints
Definition: QueryHint.h:45
static QueryHint translateQueryHint(const std::string &hint_name)
Definition: QueryHint.h:240
std::vector< std::string > list_options_
Definition: QueryHint.h:140
void registerHint(const QueryHint hint)
Definition: QueryHint.h:251
bool hasOptions() const
Definition: QueryHint.h:125
HintIdentifier(bool global_hint, const std::string &hint_name)
Definition: QueryHint.h:61
const std::vector< std::string > & getListOptions()
Definition: QueryHint.h:113
double g_overlaps_target_entries_per_bin
Definition: Execute.cpp:106
size_t g_overlaps_max_table_size_bytes
Definition: Execute.cpp:105
static RegisteredQueryHint defaults()
Definition: QueryHint.h:237
size_t overlaps_max_size
Definition: QueryHint.h:230
bool isHintRegistered(const QueryHint hint) const
Definition: QueryHint.h:256
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:263
QueryHint
Definition: QueryHint.h:29
const std::unordered_map< std::string, std::string > & getKVOptions()
Definition: QueryHint.h:117
RegisteredQueryHint operator||(const RegisteredQueryHint &global_hints) const
Definition: QueryHint.h:161
bool g_enable_watchdog false
Definition: Execute.cpp:79
bool global_hint
Definition: QueryHint.h:58
std::vector< int > inherit_paths_
Definition: QueryHint.h:139
bool has_kv_type_options_
Definition: QueryHint.h:138
double overlaps_bucket_threshold
Definition: QueryHint.h:229
QueryHint hint_
Definition: QueryHint.h:130
const QueryHint getHint() const
Definition: QueryHint.h:121
std::string hint_name
Definition: QueryHint.h:59
void setInheritPaths(std::vector< int > &interit_paths)
Definition: QueryHint.h:109
ExplainedQueryHint(QueryHint hint, bool global_hint, bool is_marker, bool has_kv_type_options, std::unordered_map< std::string, std::string > &kv_options)
Definition: QueryHint.h:90
bool isAnyQueryHintDelivered() const
Definition: QueryHint.h:246