OmniSciDB  94e8789169
 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  "RESTORE",
41  "REVOKE",
42  "SHOW",
43  "TRUNCATE",
44  "KILL"};
45 
46 const std::vector<std::string> ParserWrapper::update_dml_cmd = {
47  "INSERT",
48  "DELETE",
49  "UPDATE",
50  "UPSERT",
51 };
52 
53 const std::string ParserWrapper::explain_str = {"explain"};
54 const std::string ParserWrapper::calcite_explain_str = {"explain calcite"};
55 const std::string ParserWrapper::optimized_explain_str = {"explain optimized"};
56 const std::string ParserWrapper::plan_explain_str = {"explain plan"};
57 const std::string ParserWrapper::optimize_str = {"optimize"};
58 const std::string ParserWrapper::validate_str = {"validate"};
59 
60 extern bool g_enable_fsi;
61 extern bool g_enable_s3_fsi;
62 extern bool g_enable_calcite_ddl_parser;
63 
64 ParserWrapper::ParserWrapper(std::string query_string) {
65  query_type_ = QueryType::SchemaRead;
66  if (boost::istarts_with(query_string, calcite_explain_str)) {
67  actual_query = boost::trim_copy(query_string.substr(calcite_explain_str.size()));
68  ParserWrapper inner{actual_query};
69  if (inner.is_ddl || inner.is_update_dml) {
70  explain_type_ = ExplainType::Other;
71  return;
72  } else {
73  explain_type_ = ExplainType::Calcite;
74  return;
75  }
76  }
77 
78  if (boost::istarts_with(query_string, optimized_explain_str)) {
79  actual_query = boost::trim_copy(query_string.substr(optimized_explain_str.size()));
80  ParserWrapper inner{actual_query};
81  if (inner.is_ddl || inner.is_update_dml) {
82  explain_type_ = ExplainType::Other;
83  return;
84  } else {
85  explain_type_ = ExplainType::OptimizedIR;
86  return;
87  }
88  }
89 
90  if (boost::istarts_with(query_string, plan_explain_str)) {
91  actual_query = boost::trim_copy(query_string.substr(plan_explain_str.size()));
92  ParserWrapper inner{actual_query};
93  if (inner.is_ddl || inner.is_update_dml) {
94  explain_type_ = ExplainType::Other;
95  return;
96  } else {
97  explain_type_ = ExplainType::ExecutionPlan;
98  return;
99  }
100  }
101 
102  if (boost::istarts_with(query_string, explain_str)) {
103  actual_query = boost::trim_copy(query_string.substr(explain_str.size()));
104  ParserWrapper inner{actual_query};
105  if (inner.is_ddl || inner.is_update_dml) {
106  explain_type_ = ExplainType::Other;
107  return;
108  } else {
109  explain_type_ = ExplainType::IR;
110  return;
111  }
112  }
113 
114  if (boost::istarts_with(query_string, optimize_str)) {
115  query_type_ = QueryType::SchemaWrite;
116  is_optimize = true;
117  return;
118  }
119 
120  if (boost::istarts_with(query_string, validate_str)) {
121  is_validate = true;
122  return;
123  }
124  query_type_ = QueryType::Read;
125  for (std::string ddl : ddl_cmd) {
126  is_ddl = boost::istarts_with(query_string, ddl);
127  if (is_ddl) {
128  query_type_ = QueryType::SchemaWrite;
129  if (g_enable_fsi) {
130  std::string fsi_regex_pattern{
131  R"((CREATE|DROP|ALTER)\s+(SERVER|FOREIGN\s+TABLE).*)"};
132 
133  boost::regex fsi_regex{fsi_regex_pattern,
134  boost::regex::extended | boost::regex::icase};
135  boost::regex refresh_regex{R"(REFRESH\s+FOREIGN\s+TABLES.*)",
136  boost::regex::extended | boost::regex::icase};
137 
138  if (boost::regex_match(query_string, fsi_regex) ||
139  boost::regex_match(query_string, refresh_regex)) {
140  is_calcite_ddl_ = true;
141  is_legacy_ddl_ = false;
142  return;
143  }
144  }
145  if (ddl == "CREATE") {
146  boost::regex ctas_regex{R"(CREATE\s+TABLE.*(\"|\s)AS(\(|\s)+(SELECT|WITH).*)",
147  boost::regex::extended | boost::regex::icase};
148  if (boost::regex_match(query_string, ctas_regex)) {
149  is_ctas = true;
150  } else {
151  boost::regex create_table_regex{R"(CREATE\s+TABLE.*)",
152  boost::regex::extended | boost::regex::icase};
153  boost::regex create_view_regex{R"(CREATE\s+VIEW.*)",
154  boost::regex::extended | boost::regex::icase};
156  (boost::regex_match(query_string, create_table_regex) ||
157  boost::regex_match(query_string, create_view_regex))) {
158  is_calcite_ddl_ = true;
159  is_legacy_ddl_ = false;
160  return;
161  }
162  }
163  } else if (ddl == "COPY") {
164  is_copy = true;
165  // now check if it is COPY TO
166  boost::regex copy_to{R"(COPY\s*\(([^#])(.+)\)\s+TO\s+.*)",
167  boost::regex::extended | boost::regex::icase};
168  if (boost::regex_match(query_string, copy_to)) {
169  query_type_ = QueryType::Read;
170  is_copy_to = true;
171  } else {
172  query_type_ = QueryType::Write;
173  }
174  } else if (ddl == "SHOW") {
175  query_type_ = QueryType::SchemaRead;
176  boost::regex show_create_table_regex{
177  R"(SHOW\s+CREATE\s+TABLE\s+.*)",
178  boost::regex::extended | boost::regex::icase};
179  if (!boost::regex_match(query_string, show_create_table_regex)) {
180  is_calcite_ddl_ = true;
181  is_legacy_ddl_ = false;
182  return;
183  }
184  } else if (ddl == "DROP") {
185  query_type_ = QueryType::SchemaRead;
186  boost::regex drop_table_regex{R"(DROP\s+TABLE.*)",
187  boost::regex::extended | boost::regex::icase};
188  boost::regex drop_view_regex{R"(DROP\s+VIEW.*)",
189  boost::regex::extended | boost::regex::icase};
191  (boost::regex_match(query_string, drop_table_regex) ||
192  boost::regex_match(query_string, drop_view_regex))) {
193  is_calcite_ddl_ = true;
194  is_legacy_ddl_ = false;
195  return;
196  }
197  } else if (ddl == "KILL") {
198  query_type_ = QueryType::Unknown;
199  is_calcite_ddl_ = true;
200  is_legacy_ddl_ = false;
201  return;
202  }
203  is_legacy_ddl_ = !is_calcite_ddl_;
204  return;
205  }
206  }
207 
208  for (int i = 0; i < update_dml_cmd.size(); i++) {
209  is_update_dml = boost::istarts_with(query_string, ParserWrapper::update_dml_cmd[i]);
210  if (is_update_dml) {
211  query_type_ = QueryType::Write;
212  dml_type_ = (DMLType)(i);
213  break;
214  }
215  }
216 
217  if (dml_type_ == DMLType::Insert) {
218  boost::regex insert_regex{R"(INSERT\s+INTO.*VALUES\s*\(.*)",
219  boost::regex::extended | boost::regex::icase};
220  if (!boost::regex_match(query_string, insert_regex)) {
221  boost::regex itas_regex{R"(INSERT\s+INTO.*(\s|\(|\")+SELECT.*)",
222  boost::regex::extended | boost::regex::icase};
223  if (boost::regex_match(query_string, itas_regex)) {
224  is_itas = true;
225  }
226  }
227  }
228 }
229 
231 
233  return {explain_type_ == ExplainType::IR,
234  explain_type_ == ExplainType::OptimizedIR,
235  explain_type_ == ExplainType::ExecutionPlan,
236  explain_type_ == ExplainType::Calcite};
237 }
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
static const std::vector< std::string > ddl_cmd
bool g_enable_calcite_ddl_parser
Definition: ParserNode.cpp:72
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:91