Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}