2011-08-18 18:48:00 +00:00
# pragma once
2017-04-01 09:19:00 +00:00
# include <Parsers/IParserBase.h>
# include <Parsers/ExpressionElementParsers.h>
# include <Parsers/ExpressionListParsers.h>
# include <Parsers/ASTNameTypePair.h>
# include <Parsers/ASTColumnDeclaration.h>
# include <Parsers/ASTIdentifier.h>
2018-11-06 13:26:43 +00:00
# include <Parsers/ASTLiteral.h>
2017-04-01 09:19:00 +00:00
# include <Parsers/CommonParsers.h>
# include <Common/typeid_cast.h>
2014-10-07 09:09:59 +00:00
# include <Poco/String.h>
2011-08-18 18:48:00 +00:00
namespace DB
{
2017-05-27 17:29:55 +00:00
/** A nested table. For example, Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
2013-07-11 17:35:56 +00:00
*/
class ParserNestedTable : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " nested table " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2013-07-11 17:35:56 +00:00
} ;
2014-06-26 00:58:14 +00:00
2017-05-27 17:29:55 +00:00
/** Parametric type or Storage. For example:
* FixedString ( 10 ) or
* Partitioned ( Log , ChunkID ) or
2017-04-01 07:20:54 +00:00
* Nested ( UInt32 CounterID , FixedString ( 2 ) UserAgentMajor )
2017-05-27 17:29:55 +00:00
* Result of parsing - ASTFunction with or without parameters .
*/
2013-07-11 17:35:56 +00:00
class ParserIdentifierWithParameters : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " identifier with parameters " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2013-07-11 17:35:56 +00:00
} ;
2016-12-29 23:17:51 +00:00
/** Data type or table engine, possibly with parameters. For example, UInt8 or see examples from ParserIdentifierWithParameters
* Parse result is ASTFunction , with or without arguments .
2011-08-18 18:48:00 +00:00
*/
class ParserIdentifierWithOptionalParameters : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " identifier with optional parameters " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2011-08-18 18:48:00 +00:00
} ;
2017-09-15 12:16:12 +00:00
template < typename NameParser >
2014-05-20 16:46:33 +00:00
class IParserNameTypePair : public IParserBase
2011-08-18 18:48:00 +00:00
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " name and type pair " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2011-08-18 18:48:00 +00:00
} ;
2017-05-27 17:29:55 +00:00
/** The name and type are separated by a space. For example, URL String. */
2016-05-28 10:35:44 +00:00
using ParserNameTypePair = IParserNameTypePair < ParserIdentifier > ;
2017-05-27 17:29:55 +00:00
/** Name and type separated by a space. The name can contain a dot. For example, Hits.URL String. */
2016-05-28 10:35:44 +00:00
using ParserCompoundNameTypePair = IParserNameTypePair < ParserCompoundIdentifier > ;
2014-05-20 16:46:33 +00:00
2017-09-15 12:16:12 +00:00
template < typename NameParser >
2017-07-10 03:28:12 +00:00
bool IParserNameTypePair < NameParser > : : parseImpl ( Pos & pos , ASTPtr & node , Expected & expected )
2014-05-20 16:46:33 +00:00
{
2017-04-01 07:20:54 +00:00
NameParser name_parser ;
ParserIdentifierWithOptionalParameters type_parser ;
ASTPtr name , type ;
2017-07-10 03:28:12 +00:00
if ( name_parser . parse ( pos , name , expected )
& & type_parser . parse ( pos , type , expected ) )
2017-04-01 07:20:54 +00:00
{
2018-02-26 03:40:20 +00:00
auto name_type_pair = std : : make_shared < ASTNameTypePair > ( ) ;
2017-04-01 07:20:54 +00:00
name_type_pair - > name = typeid_cast < const ASTIdentifier & > ( * name ) . name ;
name_type_pair - > type = type ;
name_type_pair - > children . push_back ( type ) ;
node = name_type_pair ;
return true ;
}
return false ;
2014-05-20 16:46:33 +00:00
}
2011-08-18 18:48:00 +00:00
2017-05-27 17:29:55 +00:00
/** List of columns. */
2013-07-11 17:35:56 +00:00
class ParserNameTypePairList : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " name and type pair list " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2014-09-24 14:44:57 +00:00
} ;
2017-09-15 12:16:12 +00:00
template < typename NameParser >
2014-09-24 14:44:57 +00:00
class IParserColumnDeclaration : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " column declaration " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2014-09-24 14:44:57 +00:00
} ;
2016-05-28 10:35:44 +00:00
using ParserColumnDeclaration = IParserColumnDeclaration < ParserIdentifier > ;
using ParserCompoundColumnDeclaration = IParserColumnDeclaration < ParserCompoundIdentifier > ;
2014-09-24 14:44:57 +00:00
2017-09-15 12:16:12 +00:00
template < typename NameParser >
2017-07-10 03:28:12 +00:00
bool IParserColumnDeclaration < NameParser > : : parseImpl ( Pos & pos , ASTPtr & node , Expected & expected )
2014-09-24 14:44:57 +00:00
{
2017-04-01 07:20:54 +00:00
NameParser name_parser ;
ParserIdentifierWithOptionalParameters type_parser ;
2017-06-18 03:07:03 +00:00
ParserKeyword s_default { " DEFAULT " } ;
ParserKeyword s_materialized { " MATERIALIZED " } ;
ParserKeyword s_alias { " ALIAS " } ;
2018-10-01 20:16:50 +00:00
ParserKeyword s_comment { " COMMENT " } ;
2017-04-01 07:20:54 +00:00
ParserTernaryOperatorExpression expr_parser ;
2018-10-14 15:30:06 +00:00
ParserStringLiteral string_literal_parser ;
2017-04-01 07:20:54 +00:00
/// mandatory column name
ASTPtr name ;
2017-07-10 03:28:12 +00:00
if ( ! name_parser . parse ( pos , name , expected ) )
2017-04-01 07:20:54 +00:00
return false ;
/** column name should be followed by type name if it
2018-10-14 15:30:06 +00:00
* is not immediately followed by { DEFAULT , MATERIALIZED , ALIAS }
2017-04-01 07:20:54 +00:00
*/
ASTPtr type ;
const auto fallback_pos = pos ;
2017-07-10 03:28:12 +00:00
if ( ! s_default . check ( pos , expected ) & &
! s_materialized . check ( pos , expected ) & &
2018-11-13 12:08:07 +00:00
! s_alias . check ( pos , expected ) & &
! s_comment . check ( pos , expected ) )
2017-04-01 07:20:54 +00:00
{
2017-07-10 03:28:12 +00:00
type_parser . parse ( pos , type , expected ) ;
2017-04-01 07:20:54 +00:00
}
else
pos = fallback_pos ;
2018-11-13 12:08:07 +00:00
/// parse {DEFAULT, MATERIALIZED, ALIAS, COMMENT}
2017-04-01 07:20:54 +00:00
String default_specifier ;
ASTPtr default_expression ;
2018-11-13 12:08:07 +00:00
ASTPtr comment_expression ;
2017-07-10 03:28:12 +00:00
Pos pos_before_specifier = pos ;
2018-11-13 12:08:07 +00:00
if ( ! s_default . ignore ( pos , expected ) & &
! s_materialized . ignore ( pos , expected ) & &
! s_alias . ignore ( pos , expected ) & &
! s_comment . ignore ( pos , expected ) & &
! type )
return false ; /// reject sole column name without type
2017-07-10 03:28:12 +00:00
if ( s_default . ignore ( pos , expected ) | |
s_materialized . ignore ( pos , expected ) | |
s_alias . ignore ( pos , expected ) )
2017-04-01 07:20:54 +00:00
{
2017-07-10 03:28:12 +00:00
default_specifier = Poco : : toUpper ( std : : string { pos_before_specifier - > begin , pos_before_specifier - > end } ) ;
2017-04-01 07:20:54 +00:00
/// should be followed by an expression
2017-07-10 03:28:12 +00:00
if ( ! expr_parser . parse ( pos , default_expression , expected ) )
2017-04-01 07:20:54 +00:00
return false ;
}
2018-11-13 12:08:07 +00:00
else if ( s_comment . ignore ( pos , expected ) )
2018-10-01 20:16:50 +00:00
{
2018-10-14 15:30:06 +00:00
string_literal_parser . parse ( pos , comment_expression , expected ) ;
2018-10-01 20:16:50 +00:00
}
2018-11-13 12:08:07 +00:00
else if ( ! type ) // TODO: тут надо очень хорошо подумать. есть проблема с тем, что для modify column имя колонки и коммент ок, а для создания таблицы не ок.
return false ; /// reject sole column name without type
2018-10-01 20:16:50 +00:00
2018-02-26 03:40:20 +00:00
const auto column_declaration = std : : make_shared < ASTColumnDeclaration > ( ) ;
2017-04-01 07:20:54 +00:00
node = column_declaration ;
column_declaration - > name = typeid_cast < ASTIdentifier & > ( * name ) . name ;
if ( type )
{
column_declaration - > type = type ;
column_declaration - > children . push_back ( std : : move ( type ) ) ;
}
if ( default_expression )
{
column_declaration - > default_specifier = default_specifier ;
column_declaration - > default_expression = default_expression ;
column_declaration - > children . push_back ( std : : move ( default_expression ) ) ;
}
2018-10-27 20:39:59 +00:00
if ( comment_expression )
{
2018-11-08 12:03:42 +00:00
column_declaration - > comment = comment_expression ;
2018-10-01 20:16:50 +00:00
column_declaration - > children . push_back ( std : : move ( comment_expression ) ) ;
}
2017-04-01 07:20:54 +00:00
return true ;
2014-09-24 14:44:57 +00:00
}
class ParserColumnDeclarationList : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " column declaration list " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2013-07-11 17:35:56 +00:00
} ;
2017-09-18 14:18:29 +00:00
/** ENGINE = name [PARTITION BY expr] [ORDER BY expr] [SAMPLE BY expr] [SETTINGS name = value, ...] */
2017-09-17 18:49:43 +00:00
class ParserStorage : public IParserBase
2011-11-01 15:16:04 +00:00
{
protected :
2017-09-17 18:49:43 +00:00
const char * getName ( ) const { return " storage definition " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2011-11-01 15:16:04 +00:00
} ;
2017-05-27 17:29:55 +00:00
/** Query like this:
2011-10-31 06:37:12 +00:00
* CREATE | ATTACH TABLE [ IF NOT EXISTS ] [ db . ] name
2011-08-18 18:48:00 +00:00
* (
2017-04-01 07:20:54 +00:00
* name1 type1 ,
* name2 type2 ,
* . . .
2011-08-18 18:48:00 +00:00
* ) ENGINE = engine
2011-10-31 06:37:12 +00:00
*
2017-05-27 17:29:55 +00:00
* Or :
2012-07-12 20:06:45 +00:00
* CREATE | ATTACH TABLE [ IF NOT EXISTS ] [ db . ] name AS [ db2 . ] name2 [ ENGINE = engine ]
2011-11-01 15:16:04 +00:00
*
2017-05-27 17:29:55 +00:00
* Or :
2012-12-11 20:32:08 +00:00
* CREATE | ATTACH TABLE [ IF NOT EXISTS ] [ db . ] name AS ENGINE = engine SELECT . . .
2011-11-05 23:31:19 +00:00
*
2017-05-27 17:29:55 +00:00
* Or :
2016-03-19 01:18:49 +00:00
* CREATE | ATTACH DATABASE db [ ENGINE = engine ]
2014-04-24 18:49:07 +00:00
*
2017-05-27 17:29:55 +00:00
* Or :
2017-10-21 20:08:49 +00:00
* CREATE | ATTACH [ MATERIALIZED ] VIEW [ IF NOT EXISTS ] [ db . ] name [ TO [ db . ] name ] [ ENGINE = engine ] [ POPULATE ] AS SELECT . . .
2011-08-18 18:48:00 +00:00
*/
class ParserCreateQuery : public IParserBase
{
protected :
2017-04-01 07:20:54 +00:00
const char * getName ( ) const { return " CREATE TABLE or ATTACH TABLE query " ; }
2017-07-10 03:28:12 +00:00
bool parseImpl ( Pos & pos , ASTPtr & node , Expected & expected ) ;
2011-08-18 18:48:00 +00:00
} ;
}