aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Parsers/ParserExternalDDLQuery.cpp
blob: 7fa585dad747c5704314c1302955d3ee4acc5137 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "clickhouse_config.h"

#include <Parsers/ASTExternalDDLQuery.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserDropQuery.h>
#include <Parsers/ParserExternalDDLQuery.h>
#include <Parsers/ParserRenameQuery.h>

#if USE_MYSQL
#    include <Parsers/MySQL/ASTAlterQuery.h>
#    include <Parsers/MySQL/ASTCreateQuery.h>
#    include <Parsers/MySQL/ASTDropQuery.h>
#endif

namespace DB
{

#if USE_MYSQL
namespace ErrorCodes
{
    extern const int MYSQL_SYNTAX_ERROR;
}
#endif

bool ParserExternalDDLQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
    ParserFunction p_function;
    ParserKeyword s_external("EXTERNAL DDL FROM");

    ASTPtr from;
    auto external_ddl_query = std::make_shared<ASTExternalDDLQuery>();

    if (!s_external.ignore(pos, expected))
        return false;

    if (!p_function.parse(pos, from, expected))
        return false;

    external_ddl_query->set(external_ddl_query->from, from);

    bool res = false;
    if (external_ddl_query->from->name == "MySQL")
    {
#if USE_MYSQL
        MySQLParser::ParserDropQuery p_drop_query;
        ParserRenameQuery p_rename_query;
        MySQLParser::ParserAlterQuery p_alter_query;
        MySQLParser::ParserCreateQuery p_create_query;

        res = p_create_query.parse(pos, external_ddl_query->external_ddl, expected)
            || p_drop_query.parse(pos, external_ddl_query->external_ddl, expected)
            || p_alter_query.parse(pos, external_ddl_query->external_ddl, expected)
            || p_rename_query.parse(pos, external_ddl_query->external_ddl, expected);

        if (external_ddl_query->external_ddl)
            external_ddl_query->children.push_back(external_ddl_query->external_ddl);

        if (!res)
        {
            /// Syntax error is ignored, so we need to convert the error code for parsing failure

            if (ParserKeyword("ALTER TABLE").ignore(pos))
                throw Exception(ErrorCodes::MYSQL_SYNTAX_ERROR, "Cannot parse MySQL alter query.");

            if (ParserKeyword("RENAME TABLE").ignore(pos))
                throw Exception(ErrorCodes::MYSQL_SYNTAX_ERROR, "Cannot parse MySQL rename query.");

            if (ParserKeyword("DROP TABLE").ignore(pos) || ParserKeyword("TRUNCATE").ignore(pos))
                throw Exception(ErrorCodes::MYSQL_SYNTAX_ERROR, "Cannot parse MySQL drop query.");

            if (ParserKeyword("CREATE TABLE").ignore(pos) || ParserKeyword("CREATE TEMPORARY TABLE").ignore(pos))
                throw Exception(ErrorCodes::MYSQL_SYNTAX_ERROR, "Cannot parse MySQL create query.");
        }
#endif
    }

    node = external_ddl_query;
    return res;
}

}