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