diff --git a/dbms/include/DB/Interpreters/executeQuery.h b/dbms/include/DB/Interpreters/executeQuery.h index e776f8dfed9..92c59677734 100644 --- a/dbms/include/DB/Interpreters/executeQuery.h +++ b/dbms/include/DB/Interpreters/executeQuery.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include diff --git a/dbms/include/DB/Parsers/IParserBase.h b/dbms/include/DB/Parsers/IParserBase.h index f8d89b65285..05e0adf46fd 100644 --- a/dbms/include/DB/Parsers/IParserBase.h +++ b/dbms/include/DB/Parsers/IParserBase.h @@ -1,12 +1,7 @@ #pragma once -#include -#include - -#include #include -#include namespace DB { @@ -16,27 +11,7 @@ namespace DB class IParserBase : public IParser { public: - bool parse(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) - { - Pos new_max_parsed_pos = pos; - Expected new_expected = getName(); - - bool res = parseImpl(pos, end, node, new_max_parsed_pos, new_expected); - - if (new_max_parsed_pos > max_parsed_pos) - max_parsed_pos = new_max_parsed_pos; - - if (new_max_parsed_pos >= max_parsed_pos) - expected = new_expected; - - if (!res) - node = nullptr; - - if (pos > end) - throw Exception("Logical error: pos > end.", ErrorCodes::LOGICAL_ERROR); - - return res; - } + bool parse(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected); protected: virtual bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) = 0; diff --git a/dbms/include/DB/Parsers/ParserCreateQuery.h b/dbms/include/DB/Parsers/ParserCreateQuery.h index c287995290b..f86a62efe4d 100644 --- a/dbms/include/DB/Parsers/ParserCreateQuery.h +++ b/dbms/include/DB/Parsers/ParserCreateQuery.h @@ -83,7 +83,6 @@ bool IParserNameTypePair::parseImpl(Pos & pos, Pos end, ASTPtr & nod return true; } - pos = begin; return false; } @@ -119,10 +118,6 @@ bool IParserColumnDeclaration::parseImpl(Pos & pos, Pos end, ASTPtr ParserTernaryOperatorExpression expr_parser; const auto begin = pos; - const auto reset_pos_and_return = [&pos, begin] { - pos = begin; - return false; - }; /// mandatory column name ASTPtr name; @@ -160,10 +155,10 @@ bool IParserColumnDeclaration::parseImpl(Pos & pos, Pos end, ASTPtr ws.ignore(pos, end, max_parsed_pos, expected); if (!expr_parser.parse(pos, end, default_expression, max_parsed_pos, expected)) - return reset_pos_and_return(); + return false; } else if (!type) - return reset_pos_and_return(); /// reject sole column name without type + return false; /// reject sole column name without type const auto column_declaration = new ASTColumnDeclaration{StringRange{begin, pos}}; node = column_declaration; diff --git a/dbms/src/Client/Benchmark.cpp b/dbms/src/Client/Benchmark.cpp index c89630780bd..fd4350690dd 100644 --- a/dbms/src/Client/Benchmark.cpp +++ b/dbms/src/Client/Benchmark.cpp @@ -33,9 +33,6 @@ #include -#include -#include - #include #include diff --git a/dbms/src/DataTypes/DataTypeFactory.cpp b/dbms/src/DataTypes/DataTypeFactory.cpp index 9f4584ece11..afb7c289317 100644 --- a/dbms/src/DataTypes/DataTypeFactory.cpp +++ b/dbms/src/DataTypes/DataTypeFactory.cpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace DB { @@ -69,15 +70,7 @@ DataTypePtr DataTypeFactory::get(const String & name) const Array params_row; ParserExpressionList args_parser; - ASTPtr args_ast; - Expected expected = ""; - IParser::Pos pos = parameters.data(); - IParser::Pos end = pos + parameters.size(); - IParser::Pos max_parsed_pos = pos; - - if (!(args_parser.parse(pos, end, args_ast, max_parsed_pos, expected) && pos == end)) - throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR); - + ASTPtr args_ast = parseQuery(args_parser, parameters.data(), parameters.data() + parameters.size(), "parameters for data type " + name); ASTExpressionList & args_list = typeid_cast(*args_ast); if (args_list.children.empty()) @@ -121,14 +114,7 @@ DataTypePtr DataTypeFactory::get(const String & name) const if (base_name == "Nested") { ParserNameTypePairList columns_p; - ASTPtr columns_ast; - Expected expected = ""; - IParser::Pos pos = parameters.data(); - IParser::Pos end = pos + parameters.size(); - IParser::Pos max_parsed_pos = pos; - - if (!(columns_p.parse(pos, end, columns_ast, max_parsed_pos, expected) && pos == end)) - throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR); + ASTPtr columns_ast = parseQuery(columns_p, parameters.data(), parameters.data() + parameters.size(), "parameters for data type " + name); NamesAndTypesListPtr columns = new NamesAndTypesList; @@ -151,14 +137,7 @@ DataTypePtr DataTypeFactory::get(const String & name) const if (base_name == "Tuple") { ParserExpressionList columns_p; - ASTPtr columns_ast; - Expected expected = ""; - IParser::Pos pos = parameters.data(); - IParser::Pos end = pos + parameters.size(); - IParser::Pos max_parsed_pos = pos; - - if (!(columns_p.parse(pos, end, columns_ast, max_parsed_pos, expected) && pos == end)) - throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR); + ASTPtr columns_ast = parseQuery(columns_p, parameters.data(), parameters.data() + parameters.size(), "parameters for data type " + name); DataTypes elems; diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index ed20ee30054..979112d1675 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index 3cf973d7199..ae74e1f1807 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -17,8 +17,10 @@ #include #include -#include #include +#include +#include +#include #include #include @@ -409,11 +411,7 @@ ASTPtr InterpreterCreateQuery::formatColumns(const NamesAndTypesList & columns) const auto end = pos + type_name->size(); ParserIdentifierWithOptionalParameters storage_p; - Expected expected{""}; - IParser::Pos max_parsed_pos = pos; - if (!storage_p.parse(pos, end, column_declaration->type, max_parsed_pos, expected)) - throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR); - + column_declaration->type = parseQuery(storage_p, pos, end, "data type"); column_declaration->type->query_string = type_name; columns_list.children.push_back(column_declaration_ptr); } @@ -444,11 +442,7 @@ ASTPtr InterpreterCreateQuery::formatColumns(NamesAndTypesList columns, const auto end = pos + type_name->size(); ParserIdentifierWithOptionalParameters storage_p; - Expected expected{""}; - IParser::Pos max_parsed_pos = pos; - if (!storage_p.parse(pos, end, column_declaration->type, max_parsed_pos, expected)) - throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR); - + column_declaration->type = parseQuery(storage_p, pos, end, "data type"); column_declaration->type->query_string = type_name; const auto it = column_defaults.find(column.name); diff --git a/dbms/src/Interpreters/executeQuery.cpp b/dbms/src/Interpreters/executeQuery.cpp index 6b97ab3a58c..e231b91ce06 100644 --- a/dbms/src/Interpreters/executeQuery.cpp +++ b/dbms/src/Interpreters/executeQuery.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp b/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp index 01c9c2f154b..b05abadc8ff 100644 --- a/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp +++ b/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp @@ -227,15 +227,12 @@ TestResult check(const TestEntry & entry) } } -bool parse(DB::ASTPtr & ast, const std::string & query) +bool parse(DB::ASTPtr & ast, const std::string & query) { DB::ParserSelectQuery parser; - const char * pos = &query[0]; - const char * end = &query[0] + query.size(); - const char * max_parsed_pos = pos; - - DB::Expected expected = ""; - return parser.parse(pos, end, ast, max_parsed_pos, expected); + std::string message; + ast = DB::tryParseQuery(parser, query.data(), query.data() + query.size(), message, false, ""); + return !ast.isNull(); } bool equals(const DB::ASTPtr & lhs, const DB::ASTPtr & rhs) diff --git a/dbms/src/Parsers/ExpressionElementParsers.cpp b/dbms/src/Parsers/ExpressionElementParsers.cpp index 6c2a2135f67..464763c2165 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.cpp +++ b/dbms/src/Parsers/ExpressionElementParsers.cpp @@ -407,23 +407,18 @@ bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { - Pos begin = pos; - ParserNull null_p; ParserNumber num_p; ParserStringLiteral str_p; if (null_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (num_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (str_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; expected = "literal: one of nullptr, number, single quoted string"; return false; @@ -462,34 +457,27 @@ bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & if (subquery_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (paren_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (array_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (lit_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (fun_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (id_p.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; if (asterisk_p.parse(pos, end, node, max_parsed_pos, expected)) { node = new ASTAsterisk(StringRange(begin, pos)); return true; } - pos = begin; expected = "expression element: one of array, literal, function, identifier, asterisk, parenthised expression, subquery"; return false; diff --git a/dbms/src/Parsers/ExpressionListParsers.cpp b/dbms/src/Parsers/ExpressionListParsers.cpp index 1d9ce2fafb4..404f25cd14b 100644 --- a/dbms/src/Parsers/ExpressionListParsers.cpp +++ b/dbms/src/Parsers/ExpressionListParsers.cpp @@ -330,10 +330,7 @@ bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & ws.ignore(pos, end, max_parsed_pos, expected); if (!elem_parser.parse(pos, end, expression, max_parsed_pos, expected)) - { - pos = begin; return false; - } /// lambda(tuple(inner_arguments), expression) diff --git a/dbms/src/Parsers/IParserBase.cpp b/dbms/src/Parsers/IParserBase.cpp new file mode 100644 index 00000000000..3dc3a795e14 --- /dev/null +++ b/dbms/src/Parsers/IParserBase.cpp @@ -0,0 +1,36 @@ +#include + + +namespace DB +{ + +bool IParserBase::parse(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) +{ + Pos begin = pos; + Pos new_max_parsed_pos = pos; + Expected new_expected = getName(); + + bool res = parseImpl(pos, end, node, new_max_parsed_pos, new_expected); + + if (pos > new_max_parsed_pos) + new_max_parsed_pos = pos; + + if (new_max_parsed_pos > max_parsed_pos) + max_parsed_pos = new_max_parsed_pos; + + if (new_max_parsed_pos >= max_parsed_pos) + expected = new_expected; + + if (pos > end) + throw Exception("Logical error: pos > end.", ErrorCodes::LOGICAL_ERROR); + + if (!res) + { + node = nullptr; + pos = begin; + } + + return res; +} + +} diff --git a/dbms/src/Parsers/ParserCreateQuery.cpp b/dbms/src/Parsers/ParserCreateQuery.cpp index 363a7d3b022..289b91fdd7c 100644 --- a/dbms/src/Parsers/ParserCreateQuery.cpp +++ b/dbms/src/Parsers/ParserCreateQuery.cpp @@ -54,20 +54,14 @@ bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_p bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { - Pos begin = pos; - ParserFunction function_or_array; if (function_or_array.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; - ParserNestedTable nested; if (nested.parse(pos, end, node, max_parsed_pos, expected)) return true; - pos = begin; - return false; } @@ -80,10 +74,7 @@ bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPt Pos begin = pos; if (parametric.parse(pos, end, node, max_parsed_pos, expected)) - { return true; - } - pos = begin; ASTPtr ident; if (non_parametric.parse(pos, end, ident, max_parsed_pos, expected)) @@ -93,7 +84,6 @@ bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPt func->name = typeid_cast(*ident).name; return true; } - pos = begin; return false; } diff --git a/dbms/src/Parsers/ParserQuery.cpp b/dbms/src/Parsers/ParserQuery.cpp index 2f5d8c5b768..17f0443f9e9 100644 --- a/dbms/src/Parsers/ParserQuery.cpp +++ b/dbms/src/Parsers/ParserQuery.cpp @@ -52,7 +52,7 @@ bool ParserQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_ || check_p.parse(pos, end, node, max_parsed_pos, expected); /* || multi_p.parse(pos, end, node, max_parsed_pos, expected)*/; - if (!res) + if (!res && (!expected || !*expected)) expected = "One of: SHOW TABLES, SHOW DATABASES, SHOW CREATE TABLE, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE, EXISTS, DESCRIBE, DESC, ALTER, SHOW PROCESSLIST, CHECK, opening curly brace"; return res; diff --git a/dbms/src/Parsers/ParserShowTablesQuery.cpp b/dbms/src/Parsers/ParserShowTablesQuery.cpp index 6f843c8f4e4..1a0af9cebdd 100644 --- a/dbms/src/Parsers/ParserShowTablesQuery.cpp +++ b/dbms/src/Parsers/ParserShowTablesQuery.cpp @@ -76,10 +76,7 @@ bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & m return false; } else - { - pos = begin; return false; - } ws.ignore(pos, end); diff --git a/dbms/src/Parsers/ParserTablePropertiesQuery.cpp b/dbms/src/Parsers/ParserTablePropertiesQuery.cpp index 7ab8c77f203..6f0b1ef067c 100644 --- a/dbms/src/Parsers/ParserTablePropertiesQuery.cpp +++ b/dbms/src/Parsers/ParserTablePropertiesQuery.cpp @@ -44,10 +44,7 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Po ws.ignore(pos, end); if (!s_create.ignore(pos, end, max_parsed_pos, expected)) - { - pos = begin; return false; - } query_ptr = new ASTShowCreateQuery; } diff --git a/dbms/src/Parsers/parseQuery.cpp b/dbms/src/Parsers/parseQuery.cpp index a82261f4309..16de18ff6a3 100644 --- a/dbms/src/Parsers/parseQuery.cpp +++ b/dbms/src/Parsers/parseQuery.cpp @@ -40,7 +40,10 @@ static std::string getSyntaxErrorMessage( if (max_parsed_pos == end || *max_parsed_pos == ';') { - message << ": failed at end of query"; + message << ": failed at end of query.\n"; + + if (expected && *expected && *expected != '.') + message << "Expected " << expected; } else { diff --git a/dbms/src/Storages/StorageChunkMerger.cpp b/dbms/src/Storages/StorageChunkMerger.cpp index a1b00341771..964d4af9a7e 100644 --- a/dbms/src/Storages/StorageChunkMerger.cpp +++ b/dbms/src/Storages/StorageChunkMerger.cpp @@ -1,19 +1,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include #include +#include +#include #include #include #include