OmniSciDB  c07336695a
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 = {"ALTER",
32  "COPY",
33  "GRANT",
34  "CREATE",
35  "DROP",
36  "OPTIMIZE",
37  "REVOKE",
38  "SHOW",
39  "TRUNCATE"};
40 
41 const std::vector<std::string> ParserWrapper::update_dml_cmd = {
42  "INSERT",
43  "DELETE",
44  "UPDATE",
45  "UPSERT",
46 };
47 
48 const std::string ParserWrapper::explain_str = {"explain"};
49 const std::string ParserWrapper::calcite_explain_str = {"explain calcite"};
50 const std::string ParserWrapper::optimized_explain_str = {"explain optimized"};
51 const std::string ParserWrapper::optimize_str = {"optimize"};
52 const std::string ParserWrapper::validate_str = {"validate"};
53 
54 ParserWrapper::ParserWrapper(std::string query_string) {
55  if (boost::istarts_with(query_string, calcite_explain_str)) {
56  actual_query = boost::trim_copy(query_string.substr(calcite_explain_str.size()));
57  ParserWrapper inner{actual_query};
58  if (inner.is_ddl || inner.is_update_dml) {
59  explain_type_ = ExplainType::Other;
60  return;
61  } else {
62  explain_type_ = ExplainType::Calcite;
63  return;
64  }
65  }
66 
67  if (boost::istarts_with(query_string, optimized_explain_str)) {
68  actual_query = boost::trim_copy(query_string.substr(optimized_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::OptimizedIR;
75  return;
76  }
77  }
78 
79  if (boost::istarts_with(query_string, explain_str)) {
80  actual_query = boost::trim_copy(query_string.substr(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::IR;
87  return;
88  }
89  }
90 
91  if (boost::istarts_with(query_string, optimize_str)) {
92  is_optimize = true;
93  return;
94  }
95 
96  if (boost::istarts_with(query_string, validate_str)) {
97  is_validate = true;
98  return;
99  }
100 
101  for (std::string ddl : ddl_cmd) {
102  is_ddl = boost::istarts_with(query_string, ddl);
103  if (is_ddl) {
104  if (ddl == "CREATE") {
105  boost::regex ctas_regex{R"(CREATE\s+TABLE.*AS.*SELECT.*)",
106  boost::regex::extended | boost::regex::icase};
107  if (boost::regex_match(query_string, ctas_regex)) {
108  is_ctas = true;
109  }
110  } else if (ddl == "COPY") {
111  is_copy = true;
112  // now check if it is COPY TO
113  boost::regex copy_to{R"(COPY\s*\(([^#])(.+)\)\s+TO\s+.*)",
114  boost::regex::extended | boost::regex::icase};
115  if (boost::regex_match(query_string, copy_to)) {
116  is_copy_to = true;
117  }
118  }
119  return;
120  }
121  }
122 
123  for (int i = 0; i < update_dml_cmd.size(); i++) {
124  is_update_dml = boost::istarts_with(query_string, ParserWrapper::update_dml_cmd[i]);
125  if (is_update_dml) {
126  dml_type_ = (DMLType)(i);
127  break;
128  }
129  }
130 
131  if (dml_type_ == DMLType::Insert) {
132  boost::regex insert_regex{R"(INSERT\s+INTO.*VALUES\s*\(.*)",
133  boost::regex::extended | boost::regex::icase};
134  if (!boost::regex_match(query_string, insert_regex)) {
135  boost::regex itas_regex{R"(INSERT\s+INTO.*SELECT.*)",
136  boost::regex::extended | boost::regex::icase};
137  if (boost::regex_match(query_string, itas_regex)) {
138  is_itas = true;
139  }
140  }
141  }
142 }
143 
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
ParserWrapper(std::string query_string)