|
3 | 3 | // |
4 | 4 |
|
5 | 5 | #include "as_clickbench_benchmark.hpp" |
| 6 | +#include "as_query_rewriter.hpp" |
6 | 7 | #include "benchmark_json.hpp" |
7 | 8 | #include "benchmark_paths.hpp" |
8 | 9 |
|
@@ -171,133 +172,10 @@ static vector<int> ParseIntListCSV(const string &list) { |
171 | 172 | return values; |
172 | 173 | } |
173 | 174 |
|
174 | | -static bool IsIdentifierChar(char c) { |
175 | | - return std::isalnum(static_cast<unsigned char>(c)) || c == '_'; |
176 | | -} |
177 | | - |
178 | 175 | static bool IsValidSampleCount(int m) { |
179 | 176 | return m >= 64 && m <= 512 && (m & (m - 1)) == 0; |
180 | 177 | } |
181 | 178 |
|
182 | | -static idx_t FindMatchingParen(const string &sql, idx_t open_pos) { |
183 | | - int depth = 0; |
184 | | - bool in_single_quote = false; |
185 | | - bool in_double_quote = false; |
186 | | - for (idx_t i = open_pos; i < sql.size(); i++) { |
187 | | - char c = sql[i]; |
188 | | - if (in_single_quote) { |
189 | | - if (c == '\'' && i + 1 < sql.size() && sql[i + 1] == '\'') { |
190 | | - i++; |
191 | | - } else if (c == '\'') { |
192 | | - in_single_quote = false; |
193 | | - } |
194 | | - continue; |
195 | | - } |
196 | | - if (in_double_quote) { |
197 | | - if (c == '"' && i + 1 < sql.size() && sql[i + 1] == '"') { |
198 | | - i++; |
199 | | - } else if (c == '"') { |
200 | | - in_double_quote = false; |
201 | | - } |
202 | | - continue; |
203 | | - } |
204 | | - if (c == '\'') { |
205 | | - in_single_quote = true; |
206 | | - } else if (c == '"') { |
207 | | - in_double_quote = true; |
208 | | - } else if (c == '(') { |
209 | | - depth++; |
210 | | - } else if (c == ')') { |
211 | | - depth--; |
212 | | - if (depth == 0) { |
213 | | - return i; |
214 | | - } |
215 | | - } |
216 | | - } |
217 | | - return string::npos; |
218 | | -} |
219 | | - |
220 | | -static vector<string> SplitTopLevelArgs(const string &args) { |
221 | | - vector<string> result; |
222 | | - idx_t start = 0; |
223 | | - int depth = 0; |
224 | | - bool in_single_quote = false; |
225 | | - bool in_double_quote = false; |
226 | | - for (idx_t i = 0; i < args.size(); i++) { |
227 | | - char c = args[i]; |
228 | | - if (in_single_quote) { |
229 | | - if (c == '\'' && i + 1 < args.size() && args[i + 1] == '\'') { |
230 | | - i++; |
231 | | - } else if (c == '\'') { |
232 | | - in_single_quote = false; |
233 | | - } |
234 | | - continue; |
235 | | - } |
236 | | - if (in_double_quote) { |
237 | | - if (c == '"' && i + 1 < args.size() && args[i + 1] == '"') { |
238 | | - i++; |
239 | | - } else if (c == '"') { |
240 | | - in_double_quote = false; |
241 | | - } |
242 | | - continue; |
243 | | - } |
244 | | - if (c == '\'') { |
245 | | - in_single_quote = true; |
246 | | - } else if (c == '"') { |
247 | | - in_double_quote = true; |
248 | | - } else if (c == '(') { |
249 | | - depth++; |
250 | | - } else if (c == ')') { |
251 | | - depth--; |
252 | | - } else if (c == ',' && depth == 0) { |
253 | | - result.push_back(Trim(args.substr(start, i - start))); |
254 | | - start = i + 1; |
255 | | - } |
256 | | - } |
257 | | - result.push_back(Trim(args.substr(start))); |
258 | | - return result; |
259 | | -} |
260 | | - |
261 | | -static bool StartsWithFunctionCall(const string &sql, idx_t pos, const string &name, idx_t &open_pos) { |
262 | | - if (pos > 0 && IsIdentifierChar(sql[pos - 1])) { |
263 | | - return false; |
264 | | - } |
265 | | - if (sql.compare(pos, name.size(), name) != 0) { |
266 | | - return false; |
267 | | - } |
268 | | - idx_t next = pos + name.size(); |
269 | | - if (next < sql.size() && IsIdentifierChar(sql[next])) { |
270 | | - return false; |
271 | | - } |
272 | | - while (next < sql.size() && std::isspace(static_cast<unsigned char>(sql[next]))) { |
273 | | - next++; |
274 | | - } |
275 | | - if (next >= sql.size() || sql[next] != '(') { |
276 | | - return false; |
277 | | - } |
278 | | - open_pos = next; |
279 | | - return true; |
280 | | -} |
281 | | - |
282 | | -static string StripFunctionCalls(const string &sql, const string &name) { |
283 | | - string result; |
284 | | - idx_t pos = 0; |
285 | | - while (pos < sql.size()) { |
286 | | - idx_t open_pos; |
287 | | - if (StartsWithFunctionCall(sql, pos, name, open_pos)) { |
288 | | - idx_t close_pos = FindMatchingParen(sql, open_pos); |
289 | | - if (close_pos == string::npos) { |
290 | | - throw std::runtime_error("could not find closing parenthesis for " + name); |
291 | | - } |
292 | | - result += StripFunctionCalls(sql.substr(open_pos + 1, close_pos - open_pos - 1), name); |
293 | | - pos = close_pos + 1; |
294 | | - continue; |
295 | | - } |
296 | | - result.push_back(sql[pos++]); |
297 | | - } |
298 | | - return result; |
299 | | -} |
300 | | - |
301 | 179 | static string RewriteAsFunctionCall(const string &name, const vector<string> &args, int sample_count) { |
302 | 180 | (void)sample_count; |
303 | 181 | if (name == "as_noised_count") { |
@@ -343,31 +221,9 @@ static bool ContainsVariableMUnsupportedAggregate(const string &sql) { |
343 | 221 | static string RewriteAsQueryForSampleAggregation(const string &sql, int sample_count) { |
344 | 222 | static const vector<string> names = {"as_noised_count", "as_noised_sum", "as_noised_avg", "as_noised_min", |
345 | 223 | "as_noised_max"}; |
346 | | - string raw_hash_sql = StripFunctionCalls(sql, "priv_hash"); |
347 | | - string result; |
348 | | - idx_t pos = 0; |
349 | | - while (pos < raw_hash_sql.size()) { |
350 | | - bool rewritten = false; |
351 | | - for (auto &name : names) { |
352 | | - idx_t open_pos; |
353 | | - if (!StartsWithFunctionCall(raw_hash_sql, pos, name, open_pos)) { |
354 | | - continue; |
355 | | - } |
356 | | - idx_t close_pos = FindMatchingParen(raw_hash_sql, open_pos); |
357 | | - if (close_pos == string::npos) { |
358 | | - throw std::runtime_error("could not find closing parenthesis for " + name); |
359 | | - } |
360 | | - auto args = SplitTopLevelArgs(raw_hash_sql.substr(open_pos + 1, close_pos - open_pos - 1)); |
361 | | - result += RewriteAsFunctionCall(name, args, sample_count); |
362 | | - pos = close_pos + 1; |
363 | | - rewritten = true; |
364 | | - break; |
365 | | - } |
366 | | - if (!rewritten) { |
367 | | - result.push_back(raw_hash_sql[pos++]); |
368 | | - } |
369 | | - } |
370 | | - return result; |
| 224 | + static const vector<string> unsupported; |
| 225 | + benchmark::AsQueryRewriteOptions options {names, unsupported, false, false, "", false}; |
| 226 | + return benchmark::RewriteAsQuery(sql, sample_count, options, RewriteAsFunctionCall); |
371 | 227 | } |
372 | 228 |
|
373 | 229 | static int ExecuteCommand(const string &cmd) { |
|
0 commit comments