bool ParserCheckQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_check_table("CHECK TABLE"); ParserToken s_dot(TokenType::Dot); ParserIdentifier table_parser; ASTPtr table; ASTPtr database; if (!s_check_table.ignore(pos, expected)) return false; if (!table_parser.parse(pos, database, expected)) return false; if (s_dot.ignore(pos)) { if (!table_parser.parse(pos, table, expected)) return false; auto query = std::make_shared<ASTCheckQuery>(); query->database = typeid_cast<const ASTIdentifier &>(*database).name; query->table = typeid_cast<const ASTIdentifier &>(*table).name; node = query; } else { table = database; auto query = std::make_shared<ASTCheckQuery>(); query->table = typeid_cast<const ASTIdentifier &>(*table).name; node = query; } return true; }
/// Parse database.table or table. static bool parseDatabaseAndTable( ASTRenameQuery::Table & db_and_table, IParser::Pos & pos, Expected & expected) { ParserIdentifier name_p; ParserToken s_dot(TokenType::Dot); ASTPtr database; ASTPtr table; if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } db_and_table.database = database ? typeid_cast<const ASTIdentifier &>(*database).name : ""; db_and_table.table = typeid_cast<const ASTIdentifier &>(*table).name; return true; }
bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_insert_into("INSERT INTO"); ParserKeyword s_table("TABLE"); ParserKeyword s_function("FUNCTION"); ParserToken s_dot(TokenType::Dot); ParserKeyword s_values("VALUES"); ParserKeyword s_format("FORMAT"); ParserKeyword s_select("SELECT"); ParserKeyword s_with("WITH"); ParserToken s_lparen(TokenType::OpeningRoundBracket); ParserToken s_rparen(TokenType::ClosingRoundBracket); ParserIdentifier name_p; ParserList columns_p(std::make_unique<ParserCompoundIdentifier>(), std::make_unique<ParserToken>(TokenType::Comma), false); ParserFunction table_function_p; ASTPtr database; ASTPtr table; ASTPtr columns; ASTPtr format; ASTPtr select; ASTPtr table_function; /// Insertion data const char * data = nullptr; if (!s_insert_into.ignore(pos, expected)) return false; s_table.ignore(pos, expected); if (s_function.ignore(pos, expected)) { if (!table_function_p.parse(pos, table_function, expected)) return false; } else { if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } } /// Is there a list of columns if (s_lparen.ignore(pos, expected)) { if (!columns_p.parse(pos, columns, expected)) return false; if (!s_rparen.ignore(pos, expected)) return false; } Pos before_select = pos; /// VALUES or FORMAT or SELECT if (s_values.ignore(pos, expected)) { data = pos->begin; } else if (s_format.ignore(pos, expected)) { auto name_pos = pos; if (!name_p.parse(pos, format, expected)) return false; data = name_pos->end; if (data < end && *data == ';') throw Exception("You have excessive ';' symbol before data for INSERT.\n" "Example:\n\n" "INSERT INTO t (x, y) FORMAT TabSeparated\n" ";\tHello\n" "2\tWorld\n" "\n" "Note that there is no ';' just after format name, " "you need to put at least one whitespace symbol before the data.", ErrorCodes::SYNTAX_ERROR); while (data < end && (*data == ' ' || *data == '\t' || *data == '\f')) ++data; /// Data starts after the first newline, if there is one, or after all the whitespace characters, otherwise. if (data < end && *data == '\r') ++data; if (data < end && *data == '\n') ++data; } else if (s_select.ignore(pos, expected) || s_with.ignore(pos,expected)) { pos = before_select; ParserSelectWithUnionQuery select_p; select_p.parse(pos, select, expected); } else { return false; } auto query = std::make_shared<ASTInsertQuery>(); node = query; if (table_function) { query->table_function = table_function; } else { getIdentifierName(database, query->database); getIdentifierName(table, query->table); } getIdentifierName(format, query->format); query->columns = columns; query->select = select; query->data = data != end ? data : nullptr; query->end = end; if (columns) query->children.push_back(columns); if (select) query->children.push_back(select); return true; }
bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { Pos begin = pos; ParserWhitespaceOrComments ws; ParserKeyword s_exists("EXISTS"); ParserKeyword s_describe("DESCRIBE"); ParserKeyword s_desc("DESC"); ParserKeyword s_show("SHOW"); ParserKeyword s_create("CREATE"); ParserKeyword s_table("TABLE"); ParserString s_dot("."); ParserIdentifier name_p; ASTPtr database; ASTPtr table; std::shared_ptr<ASTQueryWithTableAndOutput> query; ws.ignore(pos, end); if (s_exists.ignore(pos, end, max_parsed_pos, expected)) { query = std::make_shared<ASTExistsQuery>(); } else if (s_describe.ignore(pos, end, max_parsed_pos, expected) || s_desc.ignore(pos, end, max_parsed_pos, expected)) { query = std::make_shared<ASTDescribeQuery>(); } else if (s_show.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!s_create.ignore(pos, end, max_parsed_pos, expected)) return false; query = std::make_shared<ASTShowCreateQuery>(); } else { return false; } ws.ignore(pos, end); s_table.ignore(pos, end, max_parsed_pos, expected); ws.ignore(pos, end); if (!name_p.parse(pos, end, table, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (s_dot.ignore(pos, end, max_parsed_pos, expected)) { database = table; if (!name_p.parse(pos, end, table, max_parsed_pos, expected)) return false; ws.ignore(pos, end); } ws.ignore(pos, end); query->range = StringRange(begin, pos); if (database) query->database = typeid_cast<ASTIdentifier &>(*database).name; if (table) query->table = typeid_cast<ASTIdentifier &>(*table).name; node = query; return true; }
bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { Pos begin = pos; ParserWhiteSpaceOrComments ws; ParserString s_insert("INSERT", true, true); ParserString s_into("INTO", true, true); ParserString s_dot("."); ParserString s_id("ID"); ParserString s_eq("="); ParserStringLiteral id_p; ParserString s_values("VALUES", true, true); ParserString s_format("FORMAT", true, true); ParserString s_select("SELECT", true, true); ParserString s_lparen("("); ParserString s_rparen(")"); ParserIdentifier name_p; ParserList columns_p(std::make_unique<ParserCompoundIdentifier>(), std::make_unique<ParserString>(","), false); ASTPtr database; ASTPtr table; ASTPtr columns; ASTPtr format; ASTPtr select; ASTPtr id; /// Данные для вставки const char * data = nullptr; ws.ignore(pos, end); /// INSERT INTO if (!s_insert.ignore(pos, end, max_parsed_pos, expected) || !ws.ignore(pos, end) || !s_into.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!name_p.parse(pos, end, table, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (s_dot.ignore(pos, end, max_parsed_pos, expected)) { database = table; if (!name_p.parse(pos, end, table, max_parsed_pos, expected)) return false; ws.ignore(pos, end); } ws.ignore(pos, end); if (s_id.ignore(pos, end, max_parsed_pos, expected)) { if (!s_eq.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!id_p.parse(pos, end, id, max_parsed_pos, expected)) return false; } ws.ignore(pos, end); /// Есть ли список столбцов if (s_lparen.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!columns_p.parse(pos, end, columns, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!s_rparen.ignore(pos, end, max_parsed_pos, expected)) return false; } ws.ignore(pos, end); Pos before_select = pos; /// VALUES или FORMAT или SELECT if (s_values.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); data = pos; pos = end; } else if (s_format.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!name_p.parse(pos, end, format, max_parsed_pos, expected)) return false; /// Данные начинаются после первого перевода строки, если такой есть, или после всех пробельных символов, иначе. ParserWhiteSpaceOrComments ws_without_nl(false); ws_without_nl.ignore(pos, end); if (pos != end && *pos == ';') throw Exception("You have excessive ';' symbol before data for INSERT.\n" "Example:\n\n" "INSERT INTO t (x, y) FORMAT TabSeparated\n" "1\tHello\n" "2\tWorld\n" "\n" "Note that there is no ';' in first line.", ErrorCodes::SYNTAX_ERROR); if (pos != end && *pos == '\n') ++pos; data = pos; pos = end; } else if (s_select.ignore(pos, end, max_parsed_pos, expected)) { pos = before_select; ParserSelectQuery select_p; select_p.parse(pos, end, select, max_parsed_pos, expected); } else { expected = "VALUES or FORMAT or SELECT"; return false; } auto query = std::make_shared<ASTInsertQuery>(StringRange(begin, data ? data : pos)); node = query; if (database) query->database = typeid_cast<ASTIdentifier &>(*database).name; query->table = typeid_cast<ASTIdentifier &>(*table).name; if (id) query->insert_id = safeGet<const String &>(typeid_cast<ASTLiteral &>(*id).value); if (format) query->format = typeid_cast<ASTIdentifier &>(*format).name; query->columns = columns; query->select = select; query->data = data != end ? data : NULL; query->end = end; if (columns) query->children.push_back(columns); if (select) query->children.push_back(select); return true; }
bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_exists("EXISTS"); ParserKeyword s_temporary("TEMPORARY"); ParserKeyword s_describe("DESCRIBE"); ParserKeyword s_desc("DESC"); ParserKeyword s_show("SHOW"); ParserKeyword s_create("CREATE"); ParserKeyword s_database("DATABASE"); ParserKeyword s_table("TABLE"); ParserToken s_dot(TokenType::Dot); ParserIdentifier name_p; ASTPtr database; ASTPtr table; std::shared_ptr<ASTQueryWithTableAndOutput> query; bool parse_only_database_name = false; if (s_exists.ignore(pos, expected)) { query = std::make_shared<ASTExistsQuery>(); } else if (s_show.ignore(pos, expected)) { if (!s_create.ignore(pos, expected)) return false; if (s_database.ignore(pos, expected)) { parse_only_database_name = true; query = std::make_shared<ASTShowCreateDatabaseQuery>(); } else query = std::make_shared<ASTShowCreateTableQuery>(); } else { return false; } if (parse_only_database_name) { if (!name_p.parse(pos, database, expected)) return false; } else { if (s_temporary.ignore(pos, expected)) query->temporary = true; s_table.ignore(pos, expected); if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } } if (database) query->database = typeid_cast<ASTIdentifier &>(*database).name; if (table) query->table = typeid_cast<ASTIdentifier &>(*table).name; node = query; return true; }
bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { Pos begin = pos; ParserKeyword s_alter_table("ALTER TABLE"); ParserKeyword s_add_column("ADD COLUMN"); ParserKeyword s_drop_column("DROP COLUMN"); ParserKeyword s_modify_column("MODIFY COLUMN"); ParserKeyword s_modify_primary_key("MODIFY PRIMARY KEY"); ParserKeyword s_attach_partition("ATTACH PARTITION"); ParserKeyword s_detach_partition("DETACH PARTITION"); ParserKeyword s_drop_partition("DROP PARTITION"); ParserKeyword s_attach_part("ATTACH PART"); ParserKeyword s_fetch_partition("FETCH PARTITION"); ParserKeyword s_freeze_partition("FREEZE PARTITION"); ParserKeyword s_reshard("RESHARD"); ParserKeyword s_partition("PARTITION"); ParserKeyword s_after("AFTER"); ParserKeyword s_from("FROM"); ParserKeyword s_from_partition("FROM PARTITION"); ParserKeyword s_copy("COPY"); ParserKeyword s_to("TO"); ParserKeyword s_using("USING"); ParserKeyword s_coordinate("COORDINATE"); ParserKeyword s_with("WITH"); ParserKeyword s_name("NAME"); ParserString s_dot("."); ParserString s_comma(","); ParserString s_doubledot(".."); ParserWhitespaceOrComments ws; ParserIdentifier table_parser; ParserCompoundIdentifier parser_name; ParserCompoundColumnDeclaration parser_col_decl; ParserLiteral parser_literal; ParserUnsignedInteger parser_uint; ParserStringLiteral parser_string_literal; ASTPtr table; ASTPtr database; String cluster_str; ASTPtr col_type; ASTPtr col_after; ASTPtr col_drop; auto query = std::make_shared<ASTAlterQuery>(); ws.ignore(pos, end); if (!s_alter_table.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!table_parser.parse(pos, end, database, max_parsed_pos, expected)) return false; /// Parse [db].name if (s_dot.ignore(pos, end)) { if (!table_parser.parse(pos, end, table, max_parsed_pos, expected)) return false; query->table = typeid_cast<ASTIdentifier &>(*table).name; query->database = typeid_cast<ASTIdentifier &>(*database).name; } else { table = database; query->table = typeid_cast<ASTIdentifier &>(*table).name; } ws.ignore(pos, end); if (ParserKeyword{"ON"}.ignore(pos, end, max_parsed_pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, end, cluster_str, max_parsed_pos, expected)) return false; } bool parsing_finished = false; do { ASTAlterQuery::Parameters params; ws.ignore(pos, end); if (s_add_column.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_col_decl.parse(pos, end, params.col_decl, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (s_after.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if(!parser_name.parse(pos, end, params.column, max_parsed_pos, expected)) return false; } params.type = ASTAlterQuery::ADD_COLUMN; } else if (s_drop_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; params.type = ASTAlterQuery::DROP_PARTITION; } else if (s_drop_column.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_name.parse(pos, end, params.column, max_parsed_pos, expected)) return false; params.type = ASTAlterQuery::DROP_COLUMN; params.detach = false; if (s_from_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; } } else if (s_detach_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; params.type = ASTAlterQuery::DROP_PARTITION; params.detach = true; } else if (s_attach_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; params.type = ASTAlterQuery::ATTACH_PARTITION; } else if (s_attach_part.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; params.part = true; params.type = ASTAlterQuery::ATTACH_PARTITION; } else if (s_fetch_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!s_from.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); ASTPtr ast_from; if (!parser_string_literal.parse(pos, end, ast_from, max_parsed_pos, expected)) return false; params.from = typeid_cast<const ASTLiteral &>(*ast_from).value.get<const String &>(); params.type = ASTAlterQuery::FETCH_PARTITION; } else if (s_freeze_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; ws.ignore(pos, end); /// WITH NAME 'name' - place local backup to directory with specified name if (s_with.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!s_name.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); ASTPtr ast_with_name; if (!parser_string_literal.parse(pos, end, ast_with_name, max_parsed_pos, expected)) return false; params.with_name = typeid_cast<const ASTLiteral &>(*ast_with_name).value.get<const String &>(); ws.ignore(pos, end); } params.type = ASTAlterQuery::FREEZE_PARTITION; } else if (s_modify_column.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_col_decl.parse(pos, end, params.col_decl, max_parsed_pos, expected)) return false; ws.ignore(pos, end); params.type = ASTAlterQuery::MODIFY_COLUMN; } else if (s_modify_primary_key.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!ParserString("(").ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!ParserNotEmptyExpressionList(false).parse(pos, end, params.primary_key, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!ParserString(")").ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); params.type = ASTAlterQuery::MODIFY_PRIMARY_KEY; } else if (s_reshard.ignore(pos, end, max_parsed_pos, expected)) { ParserList weighted_zookeeper_paths_p(std::make_unique<ParserWeightedZooKeeperPath>(), std::make_unique<ParserString>(","), false); ParserExpressionWithOptionalAlias parser_sharding_key_expr(false); ParserStringLiteral parser_coordinator; ws.ignore(pos, end); if (s_copy.ignore(pos, end, max_parsed_pos, expected)) params.do_copy = true; ws.ignore(pos, end); if (s_partition.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_uint.parse(pos, end, params.partition, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (s_doubledot.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!parser_uint.parse(pos, end, params.last_partition, max_parsed_pos, expected)) return false; } } ws.ignore(pos, end); if (!s_to.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!weighted_zookeeper_paths_p.parse(pos, end, params.weighted_zookeeper_paths, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!s_using.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!parser_sharding_key_expr.parse(pos, end, params.sharding_key_expr, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (s_coordinate.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!s_with.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!parser_coordinator.parse(pos, end, params.coordinator, max_parsed_pos, expected)) return false; ws.ignore(pos, end); } params.type = ASTAlterQuery::RESHARD_PARTITION; } else return false; ws.ignore(pos, end); if (!s_comma.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); parsing_finished = true; } query->addParameters(params); } while (!parsing_finished); query->range = StringRange(begin, end); query->cluster = cluster_str; node = query; return true; }
bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_create("CREATE"); ParserKeyword s_temporary("TEMPORARY"); ParserKeyword s_attach("ATTACH"); ParserKeyword s_table("TABLE"); ParserKeyword s_database("DATABASE"); ParserKeyword s_if_not_exists("IF NOT EXISTS"); ParserKeyword s_as("AS"); ParserKeyword s_view("VIEW"); ParserKeyword s_materialized("MATERIALIZED"); ParserKeyword s_populate("POPULATE"); ParserToken s_dot(TokenType::Dot); ParserToken s_lparen(TokenType::OpeningRoundBracket); ParserToken s_rparen(TokenType::ClosingRoundBracket); ParserStorage storage_p; ParserIdentifier name_p; ParserColumnsOrIndicesDeclarationList columns_or_indices_p; ParserSelectWithUnionQuery select_p; ASTPtr database; ASTPtr table; ASTPtr columns_list; ASTPtr to_database; ASTPtr to_table; ASTPtr storage; ASTPtr as_database; ASTPtr as_table; ASTPtr select; String cluster_str; bool attach = false; bool if_not_exists = false; bool is_view = false; bool is_materialized_view = false; bool is_populate = false; bool is_temporary = false; if (!s_create.ignore(pos, expected)) { if (s_attach.ignore(pos, expected)) attach = true; else return false; } if (s_temporary.ignore(pos, expected)) { is_temporary = true; } if (s_table.ignore(pos, expected)) { if (s_if_not_exists.ignore(pos, expected)) if_not_exists = true; if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } // Shortcut for ATTACH a previously detached table if (attach && (!pos.isValid() || pos.get().type == TokenType::Semicolon)) { auto query = std::make_shared<ASTCreateQuery>(); node = query; query->attach = attach; query->if_not_exists = if_not_exists; query->cluster = cluster_str; getIdentifierName(database, query->database); getIdentifierName(table, query->table); return true; } /// List of columns. if (s_lparen.ignore(pos, expected)) { if (!columns_or_indices_p.parse(pos, columns_list, expected)) return false; if (!s_rparen.ignore(pos, expected)) return false; if (!storage_p.parse(pos, storage, expected) && !is_temporary) return false; } else { storage_p.parse(pos, storage, expected); if (!s_as.ignore(pos, expected)) return false; if (!select_p.parse(pos, select, expected)) /// AS SELECT ... { /// AS [db.]table if (!name_p.parse(pos, as_table, expected)) return false; if (s_dot.ignore(pos, expected)) { as_database = as_table; if (!name_p.parse(pos, as_table, expected)) return false; } /// Optional - ENGINE can be specified. if (!storage) storage_p.parse(pos, storage, expected); } } } else if (is_temporary) return false; else if (s_database.ignore(pos, expected)) { if (s_if_not_exists.ignore(pos, expected)) if_not_exists = true; if (!name_p.parse(pos, database, expected)) return false; if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } storage_p.parse(pos, storage, expected); } else { /// VIEW or MATERIALIZED VIEW if (s_materialized.ignore(pos, expected)) { is_materialized_view = true; } else is_view = true; if (!s_view.ignore(pos, expected)) return false; if (s_if_not_exists.ignore(pos, expected)) if_not_exists = true; if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } // TO [db.]table if (ParserKeyword{"TO"}.ignore(pos, expected)) { if (!name_p.parse(pos, to_table, expected)) return false; if (s_dot.ignore(pos, expected)) { to_database = to_table; if (!name_p.parse(pos, to_table, expected)) return false; } } /// Optional - a list of columns can be specified. It must fully comply with SELECT. if (s_lparen.ignore(pos, expected)) { if (!columns_or_indices_p.parse(pos, columns_list, expected)) return false; if (!s_rparen.ignore(pos, expected)) return false; } if (is_materialized_view && !to_table) { /// Internal ENGINE for MATERIALIZED VIEW must be specified. if (!storage_p.parse(pos, storage, expected)) return false; if (s_populate.ignore(pos, expected)) is_populate = true; } /// AS SELECT ... if (!s_as.ignore(pos, expected)) return false; if (!select_p.parse(pos, select, expected)) return false; } auto query = std::make_shared<ASTCreateQuery>(); node = query; query->attach = attach; query->if_not_exists = if_not_exists; query->is_view = is_view; query->is_materialized_view = is_materialized_view; query->is_populate = is_populate; query->temporary = is_temporary; getIdentifierName(database, query->database); getIdentifierName(table, query->table); query->cluster = cluster_str; getIdentifierName(to_database, query->to_database); getIdentifierName(to_table, query->to_table); query->set(query->columns_list, columns_list); query->set(query->storage, storage); getIdentifierName(as_database, query->as_database); getIdentifierName(as_table, query->as_table); query->set(query->select, select); return true; }
bool ParserDropQuery::parseDropQuery(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_temporary("TEMPORARY"); ParserKeyword s_table("TABLE"); ParserKeyword s_database("DATABASE"); ParserToken s_dot(TokenType::Dot); ParserKeyword s_if_exists("IF EXISTS"); ParserIdentifier name_p; ASTPtr database; ASTPtr table; String cluster_str; bool if_exists = false; bool temporary = false; if (s_database.ignore(pos, expected)) { if (s_if_exists.ignore(pos, expected)) if_exists = true; if (!name_p.parse(pos, database, expected)) return false; if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } } else { if (s_temporary.ignore(pos, expected)) temporary = true; if (!s_table.ignore(pos, expected)) return false; if (s_if_exists.ignore(pos, expected)) if_exists = true; if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } } auto query = std::make_shared<ASTDropQuery>(); node = query; query->kind = ASTDropQuery::Kind::Drop; query->if_exists = if_exists; query->temporary = temporary; getIdentifierName(database, query->database); getIdentifierName(table, query->table); query->cluster = cluster_str; return true; }
bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { Pos begin = pos; ParserWhitespaceOrComments ws; ParserKeyword s_insert_into("INSERT INTO"); ParserKeyword s_dot("."); ParserKeyword s_values("VALUES"); ParserKeyword s_format("FORMAT"); ParserKeyword s_select("SELECT"); ParserKeyword s_lparen("("); ParserKeyword s_rparen(")"); ParserIdentifier name_p; ParserList columns_p(std::make_unique<ParserCompoundIdentifier>(), std::make_unique<ParserString>(","), false); ASTPtr database; ASTPtr table; ASTPtr columns; ASTPtr format; ASTPtr select; /// Insertion data const char * data = nullptr; ws.ignore(pos, end); if (!s_insert_into.ignore(pos, end, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!name_p.parse(pos, end, table, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (s_dot.ignore(pos, end, max_parsed_pos, expected)) { database = table; if (!name_p.parse(pos, end, table, max_parsed_pos, expected)) return false; ws.ignore(pos, end); } ws.ignore(pos, end); /// Is there a list of columns if (s_lparen.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!columns_p.parse(pos, end, columns, max_parsed_pos, expected)) return false; ws.ignore(pos, end); if (!s_rparen.ignore(pos, end, max_parsed_pos, expected)) return false; } ws.ignore(pos, end); Pos before_select = pos; /// VALUES or FORMAT or SELECT if (s_values.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); data = pos; pos = end; } else if (s_format.ignore(pos, end, max_parsed_pos, expected)) { ws.ignore(pos, end); if (!name_p.parse(pos, end, format, max_parsed_pos, expected)) return false; /// Data starts after the first newline, if there is one, or after all the whitespace characters, otherwise. ParserWhitespaceOrComments ws_without_nl(false); ws_without_nl.ignore(pos, end); if (pos != end && *pos == ';') throw Exception("You have excessive ';' symbol before data for INSERT.\n" "Example:\n\n" "INSERT INTO t (x, y) FORMAT TabSeparated\n" "1\tHello\n" "2\tWorld\n" "\n" "Note that there is no ';' in first line.", ErrorCodes::SYNTAX_ERROR); if (pos != end && *pos == '\n') ++pos; data = pos; pos = end; } else if (s_select.ignore(pos, end, max_parsed_pos, expected)) { pos = before_select; ParserSelectQuery select_p; select_p.parse(pos, end, select, max_parsed_pos, expected); } else { expected = "VALUES or FORMAT or SELECT"; return false; } auto query = std::make_shared<ASTInsertQuery>(StringRange(begin, data ? data : pos)); node = query; if (database) query->database = typeid_cast<ASTIdentifier &>(*database).name; query->table = typeid_cast<ASTIdentifier &>(*table).name; if (format) query->format = typeid_cast<ASTIdentifier &>(*format).name; query->columns = columns; query->select = select; query->data = data != end ? data : NULL; query->end = end; if (columns) query->children.push_back(columns); if (select) query->children.push_back(select); return true; }