提交 acd0d3c5 编写于 作者: A Alexander Tokmakov

separate parser for data type

上级 045f8048
......@@ -27,7 +27,7 @@ namespace ErrorCodes
DataTypePtr DataTypeFactory::get(const String & full_name) const
{
ParserIdentifierWithOptionalParameters parser;
ParserDataType parser;
ASTPtr ast = parseQuery(parser, full_name.data(), full_name.data() + full_name.size(), "data type", 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
return get(ast);
}
......
......@@ -379,14 +379,14 @@ bool DataTypeString::equals(const IDataType & rhs) const
static DataTypePtr create(const ASTPtr & arguments)
{
if (arguments)
if (arguments && !arguments->children.empty())
{
if (arguments->children.size() > 1)
throw Exception("String data type family mustnt have more than one argument - size in characters", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
throw Exception("String data type family mustn't have more than one argument - size in characters", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
const auto * argument = arguments->children[0]->as<ASTLiteral>();
if (!argument || argument->value.getType() != Field::Types::UInt64 || argument->value.get<UInt64>() == 0)
throw Exception("FixedString data type family may have only a number (positive integer) as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE);
throw Exception("String data type family may have only a number (positive integer) as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE);
}
return std::make_shared<DataTypeString>();
......@@ -416,8 +416,18 @@ void registerDataTypeString(DataTypeFactory & factory)
factory.registerAlias("LONGBLOB", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("BYTEA", "String", DataTypeFactory::CaseInsensitive); /// PostgreSQL
factory.registerAlias("CHARACTER LARGE OBJECT", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("CHARACTER VARYING", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("CHAR LARGE OBJECT", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("CHAR VARYING", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("VARYING CHAR", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NATIVE CHARACTER", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NATIONAL CHAR", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NATIONAL CHARACTER", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NATIONAL CHARACTER LARGE OBJECT", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NATIONAL CHARACTER VARYING", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NATIONAL CHAR VARYING", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NCHAR VARYING", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("NCHAR LARGE OBJECT", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("BINARY LARGE OBJECT", "String", DataTypeFactory::CaseInsensitive);
factory.registerAlias("BINARY VARYING", "String", DataTypeFactory::CaseInsensitive);
}
}
......@@ -63,6 +63,7 @@ void registerDataTypeNumbers(DataTypeFactory & factory)
factory.registerAlias("REAL", "Float32", DataTypeFactory::CaseInsensitive);
factory.registerAlias("SINGLE", "Float32", DataTypeFactory::CaseInsensitive); /// MS Access
factory.registerAlias("DOUBLE", "Float64", DataTypeFactory::CaseInsensitive);
factory.registerAlias("DOUBLE PRECISION", "Float64", DataTypeFactory::CaseInsensitive);
}
......
......@@ -352,7 +352,7 @@ bool ParserCastExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expect
&& ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected)
&& ParserExpression().parse(pos, expr_node, expected)
&& ParserKeyword("AS").ignore(pos, expected)
&& ParserIdentifierWithOptionalParameters().parse(pos, type_node, expected)
&& ParserDataType().parse(pos, type_node, expected)
&& ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
/// Convert to canonical representation in functional form: CAST(expr, 'type')
......@@ -1233,7 +1233,7 @@ bool ParserSubstitution::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
++pos;
auto old_pos = pos;
ParserIdentifierWithOptionalParameters type_parser;
ParserDataType type_parser;
if (!type_parser.ignore(pos, expected))
{
expected.add(pos, "substitution type");
......
......@@ -48,13 +48,6 @@ protected:
};
class ParserBareWord : public IParserBase
{
protected:
const char * getName() const override { return "bare word"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
/** An identifier, possibly containing a dot, for example, x_yz123 or `something special` or Hits.EventTime,
* possibly with UUID clause like `db name`.`table name` UUID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
*/
......@@ -363,7 +356,7 @@ protected:
bool brackets_can_be_omitted;
};
/** Data type or table engine, possibly with parameters. For example, UInt8 or see examples from ParserIdentifierWithParameters
/** Table engine, possibly with parameters. See examples from ParserIdentifierWithParameters
* Parse result is ASTFunction, with or without arguments.
*/
class ParserIdentifierWithOptionalParameters : public IParserBase
......
......@@ -53,12 +53,7 @@ bool ParserNestedTable::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserIdentifierWithParameters::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserFunction function_or_array;
if (function_or_array.parse(pos, node, expected))
return true;
ParserNestedTable nested;
return nested.parse(pos, node, expected);
return ParserFunction().parse(pos, node, expected);
}
bool ParserNameTypePairList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
......@@ -85,7 +80,7 @@ bool ParserIndexDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
ParserKeyword s_granularity("GRANULARITY");
ParserIdentifier name_p;
ParserIdentifierWithOptionalParameters ident_with_optional_params_p;
ParserDataType data_type_p;
ParserExpression expression_p;
ParserUnsignedInteger granularity_p;
......@@ -103,7 +98,7 @@ bool ParserIndexDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
if (!s_type.ignore(pos, expected))
return false;
if (!ident_with_optional_params_p.parse(pos, type, expected))
if (!data_type_p.parse(pos, type, expected))
return false;
if (!s_granularity.ignore(pos, expected))
......
......@@ -9,6 +9,7 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ParserDataType.h>
#include <Poco/String.h>
#include <boost/algorithm/string.hpp>
......@@ -27,10 +28,9 @@ protected:
};
/** Parametric type or Storage. For example:
* FixedString(10) or
* Partitioned(Log, ChunkID) or
* Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
/** Storage engine or Codec. For example:
* Memory()
* ReplicatedMergeTree('/path', 'replica')
* Result of parsing - ASTFunction with or without parameters.
*/
class ParserIdentifierWithParameters : public IParserBase
......@@ -50,14 +50,12 @@ protected:
/** The name and type are separated by a space. For example, URL String. */
using ParserNameTypePair = IParserNameTypePair<ParserIdentifier>;
/** Name and type separated by a space. The name can contain a dot. For example, Hits.URL String. */
using ParserCompoundNameTypePair = IParserNameTypePair<ParserCompoundIdentifier>;
template <typename NameParser>
bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
NameParser name_parser;
ParserIdentifierWithOptionalParameters type_parser;
ParserDataType type_parser;
ASTPtr name, type;
if (name_parser.parse(pos, name, expected)
......@@ -116,7 +114,7 @@ template <typename NameParser>
bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
NameParser name_parser;
ParserIdentifierWithOptionalParameters type_parser;
ParserDataType type_parser;
ParserKeyword s_default{"DEFAULT"};
ParserKeyword s_materialized{"MATERIALIZED"};
ParserKeyword s_alias{"ALIAS"};
......@@ -151,39 +149,6 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
{
if (!type_parser.parse(pos, type, expected))
return false;
ASTFunction * type_func = type->as<ASTFunction>();
if (!type_func->arguments)
{
if (boost::algorithm::iequals(type_func->name, "DOUBLE"))
{
if (ParserKeyword{"PRESICION"}.ignore(pos))
{
type_func->name += " PRESICION";
}
}
else if (boost::algorithm::iequals(type_func->name, "CHAR"))
{
if (ParserKeyword{"VARYING"}.ignore(pos))
{
type_func->name += " VARYING";
}
}
else if (boost::algorithm::iequals(type_func->name, "NATIVE"))
{
if (ParserKeyword{"CHARACTER"}.ignore(pos))
{
type_func->name += " CHARACTER";
}
}
else if (boost::algorithm::iequals(type_func->name, "VARYING"))
{
if (ParserKeyword{"CHAR"}.ignore(pos))
{
type_func->name += " CHAR";
}
}
}
}
Pos pos_before_specifier = pos;
......
#include <Parsers/ParserDataType.h>
#include <Parsers/ExpressionElementParsers.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ParserCreateQuery.h>
namespace DB
{
bool ParserDataType::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserNestedTable nested;
if (nested.parse(pos, node, expected))
return true;
String type_name;
ParserIdentifier name_parser;
ASTPtr identifier;
if (!name_parser.parse(pos, identifier, expected))
return false;
tryGetIdentifierNameInto(identifier, type_name);
String type_name_upper = Poco::toUpper(type_name);
String type_name_suffix;
/// Special cases for compatibility with SQL standard. We can parse several words as type name
/// only for certain first words, otherwise we don't know how many words to parse
if (type_name_upper == "NATIONAL")
{
if (ParserKeyword("CHARACTER LARGE OBJECT").ignore(pos))
type_name_suffix = "CHARACTER LARGE OBJECT";
else if (ParserKeyword("CHARACTER VARYING").ignore(pos))
type_name_suffix = "CHARACTER VARYING";
else if (ParserKeyword("CHAR VARYING").ignore(pos))
type_name_suffix = "CHAR VARYING";
else if (ParserKeyword("CHARACTER").ignore(pos))
type_name_suffix = "CHARACTER";
else if (ParserKeyword("CHAR").ignore(pos))
type_name_suffix = "CHAR";
}
else if (type_name_upper == "BINARY" ||
type_name_upper == "CHARACTER" ||
type_name_upper == "CHAR" ||
type_name_upper == "NCHAR")
{
if (ParserKeyword("LARGE OBJECT").ignore(pos))
type_name_suffix = "LARGE OBJECT";
else if (ParserKeyword("VARYING").ignore(pos))
type_name_suffix = "VARYING";
}
else if (type_name_upper == "DOUBLE")
{
if (ParserKeyword("PRECISION").ignore(pos))
type_name_suffix = "PRECISION";
}
if (!type_name_suffix.empty())
type_name = type_name_upper + " " + type_name_suffix;
auto function_node = std::make_shared<ASTFunction>();
function_node->name = type_name;
if (pos->type != TokenType::OpeningRoundBracket)
{
node = function_node;
return true;
}
++pos;
/// Parse optional parameters
ParserList args_parser(std::make_unique<ParserExpression>(), std::make_unique<ParserToken>(TokenType::Comma));
ASTPtr expr_list_args;
if (!args_parser.parse(pos, expr_list_args, expected))
return false;
if (pos->type != TokenType::ClosingRoundBracket)
return false;
++pos;
function_node->arguments = expr_list_args;
function_node->children.push_back(function_node->arguments);
node = function_node;
return true;
}
}
#pragma once
#include <Parsers/IParserBase.h>
namespace DB
{
/// Parses data type as ASTFunction
/// Examples: Int8, Array(Nullable(FixedString(16))), DOUBLE PRECISION, Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
class ParserDataType : public IParserBase
{
protected:
const char * getName() const override { return "data type"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
}
......@@ -2,6 +2,7 @@
#include <Parsers/ExpressionElementParsers.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserDataType.h>
namespace DB
{
......@@ -9,7 +10,7 @@ namespace DB
bool ParserDictionaryAttributeDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserIdentifier name_parser;
ParserIdentifierWithOptionalParameters type_parser;
ParserDataType type_parser;
ParserKeyword s_default{"DEFAULT"};
ParserKeyword s_expression{"EXPRESSION"};
ParserKeyword s_hierarchical{"HIERARCHICAL"};
......
......@@ -75,6 +75,7 @@ SRCS(
ParserCreateSettingsProfileQuery.cpp
ParserCreateUserQuery.cpp
ParserDescribeTableQuery.cpp
ParserDataType.cpp
ParserDictionary.cpp
ParserDictionaryAttributeDeclaration.cpp
ParserDropAccessEntityQuery.cpp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册