OmniSciDB  fe05a0c208
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ParserWrapper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, 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 /*
18  * File: ParserWrapper.cpp
19  * Author: michael
20  *
21  * Created on Feb 23, 2016, 9:33 AM
22  */
23 
24 #include "ParserWrapper.h"
25 #include "Shared/measure.h"
26 
27 #include <boost/algorithm/string.hpp>
28 
29 using namespace std;
30 
31 const std::vector<std::string> ParserWrapper::ddl_cmd = {"ARCHIVE",
32  "ALTER",
33  "COPY",
34  "GRANT",
35  "CREATE",
36  "DROP",
37  "DUMP",
38  "OPTIMIZE",
39  "REFRESH",
40  "RENAME",
41  "RESTORE",
42  "REVOKE",
43  "SHOW",
44  "TRUNCATE",
45  "KILL"};
46 
47 const std::vector<std::string> ParserWrapper::update_dml_cmd = {
48  "INSERT",
49  "DELETE",
50  "UPDATE",
51  "UPSERT",
52 };
53 
54 const std::string ParserWrapper::explain_str = {"explain"};
55 const std::string ParserWrapper::calcite_explain_str = {"explain calcite"};
56 const std::string ParserWrapper::optimized_explain_str = {"explain optimized"};
57 const std::string ParserWrapper::plan_explain_str = {"explain plan"};
58 const std::string ParserWrapper::optimize_str = {"optimize"};
59 const std::string ParserWrapper::validate_str = {"validate"};
60 
61 extern bool g_enable_fsi;
62 extern bool g_enable_s3_fsi;
63 extern bool g_enable_calcite_ddl_parser;
64 
65 ParserWrapper::ParserWrapper(std::string query_string) {
66  query_type_ = QueryType::SchemaRead;
67  if (boost::istarts_with(query_string, calcite_explain_str)) {
68  actual_query = boost::trim_copy(query_string.substr(calcite_explain_str.size()));
69  ParserWrapper inner{actual_query};
70  if (inner.is_ddl || inner.is_update_dml) {
71  explain_type_ = ExplainType::Other;
72  return;
73  } else {
74  explain_type_ = ExplainType::Calcite;
75  return;
76  }
77  }
78 
79  if (boost::istarts_with(query_string, optimized_explain_str)) {
80  actual_query = boost::trim_copy(query_string.substr(optimized_explain_str.size()));
81  ParserWrapper inner{actual_query};
82  if (inner.is_ddl || inner.is_update_dml) {
83  explain_type_ = ExplainType::Other;
84  return;
85  } else {
86  explain_type_ = ExplainType::OptimizedIR;
87  return;
88  }
89  }
90 
91  if (boost::istarts_with(query_string, plan_explain_str)) {
92  actual_query = boost::trim_copy(query_string.substr(plan_explain_str.size()));
93  ParserWrapper inner{actual_query};
94  if (inner.is_ddl || inner.is_update_dml) {
95  explain_type_ = ExplainType::Other;
96  return;
97  } else {
98  explain_type_ = ExplainType::ExecutionPlan;
99  return;
100  }
101  }
102 
103  if (boost::istarts_with(query_string, explain_str)) {
104  actual_query = boost::trim_copy(query_string.substr(explain_str.size()));
105  ParserWrapper inner{actual_query};
106  if (inner.is_ddl || inner.is_update_dml) {
107  explain_type_ = ExplainType::Other;
108  return;
109  } else {
110  explain_type_ = ExplainType::IR;
111  return;
112  }
113  }
114 
115  if (boost::istarts_with(query_string, optimize_str)) {
116  query_type_ = QueryType::SchemaWrite;
117  is_optimize = true;
118  return;
119  }
120 
121  if (boost::istarts_with(query_string, validate_str)) {
122  is_validate = true;
123  return;
124  }
125 
126  query_type_ = QueryType::Read;
127  for (std::string ddl : ddl_cmd) {
128  is_ddl = boost::istarts_with(query_string, ddl);
129  if (is_ddl) {
130  query_type_ = QueryType::SchemaWrite;
131  if (g_enable_fsi) {
132  std::string fsi_regex_pattern{
133  R"((CREATE|DROP|ALTER)\s+(SERVER|FOREIGN\s+TABLE).*)"};
134 
135  boost::regex fsi_regex{fsi_regex_pattern,
136  boost::regex::extended | boost::regex::icase};
137  boost::regex refresh_regex{R"(REFRESH\s+FOREIGN\s+TABLES.*)",
138  boost::regex::extended | boost::regex::icase};
139 
140  if (boost::regex_match(query_string, fsi_regex) ||
141  boost::regex_match(query_string, refresh_regex)) {
142  is_calcite_ddl_ = true;
143  is_legacy_ddl_ = false;
144  return;
145  }
146  }
147  if (ddl == "CREATE") {
148  boost::regex ctas_regex{R"(CREATE\s+TABLE.*(\"|\s)AS(\(|\s)+(SELECT|WITH).*)",
149  boost::regex::extended | boost::regex::icase};
150  if (boost::regex_match(query_string, ctas_regex)) {
151  is_ctas = true;
152  } else {
153  boost::regex create_table_regex{R"(CREATE\s+TABLE.*)",
154  boost::regex::extended | boost::regex::icase};
155  boost::regex create_view_regex{R"(CREATE\s+VIEW.*)",
156  boost::regex::extended | boost::regex::icase};
158  (boost::regex_match(query_string, create_table_regex) ||
159  boost::regex_match(query_string, create_view_regex))) {
160  is_calcite_ddl_ = true;
161  is_legacy_ddl_ = false;
162  return;
163  }
164  }
165  } else if (ddl == "COPY") {
166  is_copy = true;
167  // now check if it is COPY TO
168  boost::regex copy_to{R"(COPY\s*\(([^#])(.+)\)\s+TO\s+.*)",
169  boost::regex::extended | boost::regex::icase};
170  if (boost::regex_match(query_string, copy_to)) {
171  query_type_ = QueryType::Read;
172  is_copy_to = true;
173  } else {
174  query_type_ = QueryType::Write;
175  }
176  } else if (ddl == "SHOW") {
177  query_type_ = QueryType::SchemaRead;
178  boost::regex show_create_table_regex{
179  R"(SHOW\s+CREATE\s+TABLE\s+.*)",
180  boost::regex::extended | boost::regex::icase};
181  if (!boost::regex_match(query_string, show_create_table_regex)) {
182  is_calcite_ddl_ = true;
183  is_legacy_ddl_ = false;
184  return;
185  }
186  } else if (ddl == "DROP") {
187  boost::regex drop_table_regex{R"(DROP\s+TABLE.*)",
188  boost::regex::extended | boost::regex::icase};
189  boost::regex drop_view_regex{R"(DROP\s+VIEW.*)",
190  boost::regex::extended | boost::regex::icase};
192  (boost::regex_match(query_string, drop_table_regex) ||
193  boost::regex_match(query_string, drop_view_regex))) {
194  is_calcite_ddl_ = true;
195  is_legacy_ddl_ = false;
196  return;
197  }
198  } else if (ddl == "KILL") {
199  query_type_ = QueryType::Unknown;
200  is_calcite_ddl_ = true;
201  is_legacy_ddl_ = false;
202  return;
203  } else if (ddl == "RENAME") {
204  query_type_ = QueryType::SchemaWrite;
205  is_calcite_ddl_ = true;
206  is_legacy_ddl_ = false;
207  return;
208  } else if (ddl == "ALTER") {
209  query_type_ = QueryType::SchemaWrite;
210  boost::regex alter_table_regex{R"(ALTER\s+TABLE.*)",
211  boost::regex::extended | boost::regex::icase};
213  boost::regex_match(query_string, alter_table_regex)) {
214  is_calcite_ddl_ = true;
215  is_legacy_ddl_ = false;
216  return;
217  }
218  }
219  is_legacy_ddl_ = !is_calcite_ddl_;
220  return;
221  }
222  }
223 
224  for (int i = 0; i < update_dml_cmd.size(); i++) {
225  is_update_dml = boost::istarts_with(query_string, ParserWrapper::update_dml_cmd[i]);
226  if (is_update_dml) {
227  query_type_ = QueryType::Write;
228  dml_type_ = (DMLType)(i);
229  break;
230  }
231  }
232 
233  if (dml_type_ == DMLType::Insert) {
234  boost::regex insert_regex{R"(INSERT\s+INTO.*VALUES\s*\(.*)",
235  boost::regex::extended | boost::regex::icase};
236  if (!boost::regex_match(query_string, insert_regex)) {
237  boost::regex itas_regex{R"(INSERT\s+INTO.*(\s|\(|\")+SELECT.*)",
238  boost::regex::extended | boost::regex::icase};
239  if (boost::regex_match(query_string, itas_regex)) {
240  is_itas = true;
241  }
242  }
243  }
244 }
245 
247 
249  return {explain_type_ == ExplainType::IR,
250  explain_type_ == ExplainType::OptimizedIR,
251  explain_type_ == ExplainType::ExecutionPlan,
252  explain_type_ == ExplainType::Calcite};
253 }
Classes used to wrap parser calls for calcite redirection.
static const std::string optimize_str
virtual ~ParserWrapper()
static const std::string optimized_explain_str
ExplainInfo getExplainInfo() const
static const std::string calcite_explain_str
bool g_enable_s3_fsi
Definition: Catalog.cpp:93
static const std::vector< std::string > ddl_cmd
bool g_enable_calcite_ddl_parser
Definition: ParserNode.cpp:74
static const std::string validate_str
static const std::string explain_str
static const std::vector< std::string > update_dml_cmd
static const std::string plan_explain_str
ParserWrapper(std::string query_string)
bool g_enable_fsi
Definition: Catalog.cpp:92