OmniSciDB  d2f719934e
 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,
38  kHintCount, // should be at the last elem before INVALID enum value to count #
39  // supported hints correctly
40  kInvalidHint // this should be the last elem of this enum
41 };
42 
43 static const std::unordered_map<std::string, QueryHint> SupportedQueryHints = {
44  {"cpu_mode", QueryHint::kCpuMode},
45  {"columnar_output", QueryHint::kColumnarOutput},
46  {"rowwise_output", QueryHint::kRowwiseOutput},
47  {"overlaps_bucket_threshold", QueryHint::kOverlapsBucketThreshold},
48  {"overlaps_max_size", QueryHint::kOverlapsMaxSize},
49  {"overlaps_allow_gpu_build", QueryHint::kOverlapsAllowGpuBuild},
50  {"overlaps_no_cache", QueryHint::kOverlapsNoCache},
51  {"overlaps_keys_per_bin", QueryHint::kOverlapsKeysPerBin}};
52 
55  std::string hint_name;
56 
57  HintIdentifier(bool global_hint, const std::string& hint_name)
58  : global_hint(global_hint), hint_name(hint_name){};
59 };
60 
62  // this class represents parsed query hint's specification
63  // our query AST analyzer translates query hint string to understandable form which we
64  // called "ExplainedQueryHint"
65  public:
67  bool global_hint,
68  bool is_marker,
69  bool has_kv_type_options)
70  : hint_(hint)
71  , global_hint_(global_hint)
72  , is_marker_(is_marker)
73  , has_kv_type_options_(has_kv_type_options) {}
74 
76  bool global_hint,
77  bool is_marker,
78  bool has_kv_type_options,
79  std::vector<std::string>& list_options)
80  : hint_(hint)
81  , global_hint_(global_hint)
82  , is_marker_(is_marker)
83  , has_kv_type_options_(has_kv_type_options)
84  , list_options_(std::move(list_options)) {}
85 
87  bool global_hint,
88  bool is_marker,
89  bool has_kv_type_options,
90  std::unordered_map<std::string, std::string>& kv_options)
91  : hint_(hint)
92  , global_hint_(global_hint)
93  , is_marker_(is_marker)
94  , has_kv_type_options_(has_kv_type_options)
95  , kv_options_(std::move(kv_options)) {}
96 
97  void setListOptions(std::vector<std::string>& list_options) {
98  list_options_ = list_options;
99  }
100 
101  void setKVOptions(std::unordered_map<std::string, std::string>& kv_options) {
102  kv_options_ = kv_options;
103  }
104 
105  void setInheritPaths(std::vector<int>& interit_paths) {
106  inherit_paths_ = interit_paths;
107  }
108 
109  const std::vector<std::string>& getListOptions() { return list_options_; }
110 
111  const std::vector<int>& getInteritPath() { return inherit_paths_; }
112 
113  const std::unordered_map<std::string, std::string>& getKVOptions() {
114  return kv_options_;
115  }
116 
117  const QueryHint getHint() const { return hint_; }
118 
119  bool isGlobalHint() const { return global_hint_; }
120 
121  bool hasOptions() const { return is_marker_; }
122 
123  bool hasKvOptions() const { return has_kv_type_options_; }
124 
125  private:
127  // Set true if this hint affects globally
128  // Otherwise it just affects the node which this hint is included (aka table hint)
130  // set true if this has no extra options (neither list_options nor kv_options)
132  // Set true if it is not a marker and has key-value type options
133  // Otherwise (it is not a marker but has list type options), we set this be false
135  std::vector<int> inherit_paths_; // currently not used
136  std::vector<std::string> list_options_;
137  std::unordered_map<std::string, std::string> kv_options_;
138 };
139 
141  // for each query hint, we first translate the raw query hint info
142  // to understandable form called "ExplainedQueryHint"
143  // and we get all necessary info from it and organize it into "RegisteredQueryHint"
144  // so by using "RegisteredQueryHint", we can know and access which query hint is
145  // registered and its detailed info such as the hint's parameter values given by user
147  : cpu_mode(false)
150  , overlaps_bucket_threshold(std::numeric_limits<double>::max())
156 
158  CHECK_EQ(registered_hint.size(), global_hints.registered_hint.size());
159  // apply registered global hint to the local hint if necessary
160  // we prioritize global hint when both side of hints are enabled simultaneously
161  RegisteredQueryHint updated_query_hints(*this);
162 
163  int num_hints = static_cast<int>(QueryHint::kHintCount);
164  for (int i = 0; i < num_hints; ++i) {
165  if (global_hints.registered_hint.at(i)) {
166  updated_query_hints.registered_hint.at(i) = global_hints.registered_hint[i];
167  switch (i) {
168  case static_cast<int>(QueryHint::kCpuMode): {
169  updated_query_hints.cpu_mode = true;
170  break;
171  }
172  case static_cast<int>(QueryHint::kColumnarOutput): {
173  updated_query_hints.columnar_output = true;
174  break;
175  }
176  case static_cast<int>(QueryHint::kRowwiseOutput): {
177  updated_query_hints.rowwise_output = true;
178  break;
179  }
180  case static_cast<int>(QueryHint::kOverlapsBucketThreshold): {
181  updated_query_hints.overlaps_bucket_threshold =
182  global_hints.overlaps_bucket_threshold;
183  break;
184  }
185  case static_cast<int>(QueryHint::kOverlapsMaxSize): {
186  updated_query_hints.overlaps_max_size = global_hints.overlaps_max_size;
187  break;
188  }
189  case static_cast<int>(QueryHint::kOverlapsAllowGpuBuild): {
190  updated_query_hints.overlaps_allow_gpu_build = true;
191  break;
192  }
193  case static_cast<int>(QueryHint::kOverlapsNoCache): {
194  updated_query_hints.overlaps_no_cache = true;
195  break;
196  }
197  case static_cast<int>(QueryHint::kOverlapsKeysPerBin): {
198  updated_query_hints.overlaps_keys_per_bin =
199  global_hints.overlaps_keys_per_bin;
200  break;
201  }
202  }
203  }
204  }
205  return updated_query_hints;
206  }
207 
208  // general query execution
209  bool cpu_mode;
212 
213  // overlaps hash join
214  double overlaps_bucket_threshold; // defined in "OverlapsJoinHashTable.h"
219 
220  std::vector<bool> registered_hint;
221 
223 
224  public:
225  static QueryHint translateQueryHint(const std::string& hint_name) {
226  const auto lowered_hint_name = boost::algorithm::to_lower_copy(hint_name);
227  auto it = SupportedQueryHints.find(lowered_hint_name);
228  return it == SupportedQueryHints.end() ? QueryHint::kInvalidHint : it->second;
229  }
230 
231  bool isAnyQueryHintDelivered() const {
232  const auto identity = [](const bool b) { return b; };
233  return std::any_of(registered_hint.begin(), registered_hint.end(), identity);
234  }
235 
236  void registerHint(const QueryHint hint) {
237  const auto hint_class = static_cast<int>(hint);
238  registered_hint.at(hint_class) = true;
239  }
240 
241  bool isHintRegistered(const QueryHint hint) const {
242  const auto hint_class = static_cast<int>(hint);
243  return registered_hint.at(hint_class);
244  }
245 };
246 
247 // a map from hint_name to its detailed info
248 using Hints = std::unordered_map<QueryHint, ExplainedQueryHint>;
249 
250 #endif // OMNISCI_QUERYHINT_H
std::unordered_map< std::string, std::string > kv_options_
Definition: QueryHint.h:137
#define CHECK_EQ(x, y)
Definition: Logger.h:219
bool isGlobalHint() const
Definition: QueryHint.h:119
const std::vector< int > & getInteritPath()
Definition: QueryHint.h:111
bool overlaps_allow_gpu_build
Definition: QueryHint.h:216
void setListOptions(std::vector< std::string > &list_options)
Definition: QueryHint.h:97
double overlaps_keys_per_bin
Definition: QueryHint.h:218
ExplainedQueryHint(QueryHint hint, bool global_hint, bool is_marker, bool has_kv_type_options)
Definition: QueryHint.h:66
std::vector< bool > registered_hint
Definition: QueryHint.h:220
void setKVOptions(std::unordered_map< std::string, std::string > &kv_options)
Definition: QueryHint.h:101
ExplainedQueryHint(QueryHint hint, bool global_hint, bool is_marker, bool has_kv_type_options, std::vector< std::string > &list_options)
Definition: QueryHint.h:75
bool hasKvOptions() const
Definition: QueryHint.h:123
static const std::unordered_map< std::string, QueryHint > SupportedQueryHints
Definition: QueryHint.h:43
static QueryHint translateQueryHint(const std::string &hint_name)
Definition: QueryHint.h:225
std::vector< std::string > list_options_
Definition: QueryHint.h:136
void registerHint(const QueryHint hint)
Definition: QueryHint.h:236
bool hasOptions() const
Definition: QueryHint.h:121
HintIdentifier(bool global_hint, const std::string &hint_name)
Definition: QueryHint.h:57
const std::vector< std::string > & getListOptions()
Definition: QueryHint.h:109
double g_overlaps_target_entries_per_bin
Definition: Execute.cpp:102
size_t g_overlaps_max_table_size_bytes
Definition: Execute.cpp:101
static RegisteredQueryHint defaults()
Definition: QueryHint.h:222
size_t overlaps_max_size
Definition: QueryHint.h:215
bool isHintRegistered(const QueryHint hint) const
Definition: QueryHint.h:241
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:248
QueryHint
Definition: QueryHint.h:29
const std::unordered_map< std::string, std::string > & getKVOptions()
Definition: QueryHint.h:113
RegisteredQueryHint operator||(const RegisteredQueryHint &global_hints) const
Definition: QueryHint.h:157
bool g_enable_watchdog false
Definition: Execute.cpp:76
bool global_hint
Definition: QueryHint.h:54
std::vector< int > inherit_paths_
Definition: QueryHint.h:135
bool has_kv_type_options_
Definition: QueryHint.h:134
double overlaps_bucket_threshold
Definition: QueryHint.h:214
QueryHint hint_
Definition: QueryHint.h:126
const QueryHint getHint() const
Definition: QueryHint.h:117
std::string hint_name
Definition: QueryHint.h:55
void setInheritPaths(std::vector< int > &interit_paths)
Definition: QueryHint.h:105
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:86
bool isAnyQueryHintDelivered() const
Definition: QueryHint.h:231