forked from ClickHouse/ClickHouse
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
1,706 additions
and
36 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#include "HTTPQueryAST.h" | ||
|
||
#include <Parsers/CommonParsers.h> | ||
#include <Parsers/ExpressionListParsers.h> | ||
#include <Parsers/IAST.h> | ||
#include <Parsers/IParser.h> | ||
#include <Parsers/TokenIterator.h> | ||
|
||
namespace DB | ||
{ | ||
|
||
namespace | ||
{ | ||
|
||
static constexpr auto kColumns = "columns"; | ||
static constexpr auto kSelect = "select"; | ||
static constexpr auto kWhere = "where"; | ||
static constexpr auto kOrder = "order"; | ||
|
||
template <typename T> | ||
ASTPtr parseExpression(const std::string & expression, const std::optional<ParserKeyword> & keyword = std::nullopt) | ||
{ | ||
ASTPtr ast; | ||
Tokens tokens(expression.c_str(), expression.c_str() + expression.size()); | ||
IParser::Pos pos(tokens, 0, 0); | ||
Expected expected; | ||
|
||
ParserKeyword s_select(Keyword::SELECT); | ||
|
||
if (keyword.has_value()) | ||
s_select.ignore(pos, expected); | ||
|
||
T(false).parse(pos, ast, expected); | ||
return ast; | ||
} | ||
|
||
ASTPtr parseSelect(const std::string & select) | ||
{ | ||
ParserKeyword s_select(Keyword::SELECT); | ||
|
||
ASTPtr result; | ||
Tokens tokens(select.c_str(), select.c_str() + select.size()); | ||
IParser::Pos pos(tokens, 0, 0); | ||
Expected expected; | ||
|
||
s_select.ignore(pos, expected); | ||
|
||
ParserNotEmptyExpressionList(false).parse(pos, result, expected); | ||
return result; | ||
} | ||
|
||
ASTPtr parseColumns(const std::string & columns) | ||
{ | ||
ASTPtr result; | ||
Tokens tokens(columns.c_str(), columns.c_str() + columns.size()); | ||
IParser::Pos pos(tokens, 0, 0); | ||
Expected expected; | ||
|
||
ParserNotEmptyExpressionList(false).parse(pos, result, expected); | ||
return result; | ||
} | ||
|
||
ASTPtr parseWhere(const std::string & where) | ||
{ | ||
ASTPtr result; | ||
Tokens tokens(where.c_str(), where.c_str() + where.size()); | ||
IParser::Pos pos(tokens, 0, 0); | ||
Expected expected; | ||
|
||
ParserExpressionWithOptionalAlias(false).parse(pos, result, expected); | ||
return result; | ||
} | ||
|
||
ASTPtr parseOrder(const std::string & order) | ||
{ | ||
ASTPtr result; | ||
Tokens tokens(order.c_str(), order.c_str() + order.size()); | ||
IParser::Pos pos(tokens, 0, 0); | ||
Expected expected; | ||
|
||
ParserOrderByExpressionList().parse(pos, result, expected); | ||
return result; | ||
} | ||
|
||
} | ||
|
||
HTTPQueryAST getHTTPQueryAST(HTMLForm & params) | ||
{ | ||
HTTPQueryAST result; | ||
|
||
for (const auto & [key, value] : params) | ||
if (key == kColumns) | ||
result.select_expressions.push_back(parseColumns(value)); | ||
else if (key == kSelect) | ||
result.select_expressions.push_back(parseSelect(value)); | ||
else if (key == kWhere) | ||
result.where_expressions.push_back(parseWhere(value)); | ||
else if (key == kOrder) | ||
result.order_expressions.push_back(parseOrder(value)); | ||
|
||
return result; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
|
||
#include <optional> | ||
|
||
#include <Parsers/IAST_fwd.h> | ||
#include <Server/HTTP/HTMLForm.h> | ||
|
||
namespace DB | ||
{ | ||
|
||
struct HTTPQueryAST | ||
{ | ||
std::vector<ASTPtr> select_expressions; | ||
std::vector<ASTPtr> where_expressions; | ||
std::vector<ASTPtr> order_expressions; | ||
}; | ||
|
||
HTTPQueryAST getHTTPQueryAST(HTMLForm & params); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#include "TabularHandler.h" | ||
#include "Parsers/ASTAsterisk.h" | ||
#include "Parsers/ASTExpressionList.h" | ||
#include "Parsers/ASTIdentifier.h" | ||
#include "Parsers/ASTTablesInSelectQuery.h" | ||
#include "Interpreters/executeQuery.h" | ||
|
||
#include <Parsers/ASTSelectQuery.h> | ||
#include "Parsers/ExpressionListParsers.h" | ||
#include "Parsers/formatAST.h" | ||
|
||
#include <optional> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <Interpreters/Context.h> | ||
#include <Poco/URI.h> | ||
|
||
namespace DB | ||
{ | ||
|
||
static const std::unordered_set<std::string> kQueryParameters = {"where", "columns", "select", "order", "format", "query"}; | ||
static constexpr auto kWhere = "where"; | ||
|
||
TabularHandler::TabularHandler(IServer & server_, const std::optional<String> & content_type_override_) | ||
: HTTPHandler(server_, "TabularHandler", content_type_override_), log(getLogger("TabularHandler")) | ||
{ | ||
} | ||
|
||
std::string TabularHandler::getQuery(HTTPServerRequest & request, HTMLForm & /*params*/, ContextMutablePtr context) | ||
{ | ||
auto uri = Poco::URI(request.getURI()); | ||
|
||
std::vector<std::string> path_segments; | ||
uri.getPathSegments(path_segments); | ||
|
||
const auto database = path_segments[1]; | ||
const auto table_with_format = path_segments[2]; | ||
|
||
auto pos = table_with_format.rfind('.'); | ||
std::string table = table_with_format.substr(0, pos); | ||
std::string format = table_with_format.substr(pos + 1); | ||
|
||
auto select_query = std::make_shared<ASTSelectQuery>(); | ||
|
||
auto select_expression_list = std::make_shared<ASTExpressionList>(); | ||
select_expression_list->children.push_back(std::make_shared<ASTAsterisk>()); | ||
select_query->setExpression(ASTSelectQuery::Expression::SELECT, select_expression_list); | ||
|
||
auto table_expression = std::make_shared<ASTTableExpression>(); | ||
table_expression->database_and_table_name = std::make_shared<ASTTableIdentifier>(database, table); | ||
auto tables_in_select_query = std::make_shared<ASTTablesInSelectQuery>(); | ||
auto tables_in_select_element = std::make_shared<ASTTablesInSelectQueryElement>(); | ||
tables_in_select_element->table_expression = table_expression; | ||
tables_in_select_query->children.push_back(tables_in_select_element); | ||
select_query->setExpression(ASTSelectQuery::Expression::TABLES, tables_in_select_query); | ||
|
||
const auto & query_parameters = context->getQueryParameters(); | ||
|
||
if (query_parameters.contains(kWhere)) | ||
{ | ||
const auto & where_raw = query_parameters.at(kWhere); | ||
ASTPtr where_expression; | ||
Tokens tokens(where_raw.c_str(), where_raw.c_str() + where_raw.size()); | ||
IParser::Pos new_pos(tokens, 0, 0); | ||
Expected expected; | ||
|
||
ParserExpressionWithOptionalAlias(false).parse(new_pos, where_expression, expected); | ||
select_query->setExpression(ASTSelectQuery::Expression::WHERE, std::move(where_expression)); | ||
} | ||
|
||
// Convert AST to query string | ||
WriteBufferFromOwnString query_buffer; | ||
formatAST(*select_query, query_buffer, false); | ||
std::string query_str = query_buffer.str(); | ||
|
||
// Append FORMAT clause | ||
query_str += " FORMAT " + format; | ||
|
||
LOG_INFO(log, "TabularHandler LOG {}", query_str); | ||
|
||
return query_str; | ||
// LOG_INFO(log, "TabularHandler LOG {}", request.getURI()); | ||
} | ||
|
||
|
||
bool TabularHandler::customizeQueryParam(ContextMutablePtr context, const std::string & key, const std::string & value) | ||
{ | ||
if (kQueryParameters.contains(key) && !context->getQueryParameters().contains(key)) | ||
{ | ||
context->setQueryParameter(key, value); | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} // namespace DB |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#pragma once | ||
|
||
#include <optional> | ||
#include <string> | ||
|
||
#include <Interpreters/Context_fwd.h> | ||
#include <Server/HTTPHandler.h> | ||
#include <Poco/Logger.h> | ||
|
||
namespace DB | ||
{ | ||
|
||
class TabularHandler : public HTTPHandler | ||
{ | ||
private: | ||
LoggerPtr log; | ||
|
||
std::optional<std::string> where; | ||
|
||
public: | ||
TabularHandler(IServer & server_, const std::optional<String> & content_type_override_ = std::nullopt); | ||
|
||
std::string getQuery(HTTPServerRequest & request, HTMLForm & params, ContextMutablePtr context) override; | ||
|
||
bool customizeQueryParam(ContextMutablePtr context, const std::string & key, const std::string & value) override; | ||
}; | ||
|
||
} |