From 6a69b8efa79d6637ffa49cb3bd62b0c02c08987d Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 23 Apr 2021 12:02:51 -0400 Subject: LibSQL: Fix handling of optional AS keywords In some syntaxes, using the 'AS' keyword to define an alias is optional. But if it does appear, an identifier better appear afterwards. --- Userland/Libraries/LibSQL/Parser.cpp | 17 ++++++----------- .../Libraries/LibSQL/Tests/TestSqlStatementParser.cpp | 4 ++++ 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'Userland/Libraries/LibSQL') diff --git a/Userland/Libraries/LibSQL/Parser.cpp b/Userland/Libraries/LibSQL/Parser.cpp index 79eadfb285..7ed51e7f7e 100644 --- a/Userland/Libraries/LibSQL/Parser.cpp +++ b/Userland/Libraries/LibSQL/Parser.cpp @@ -822,11 +822,9 @@ NonnullRefPtr Parser::parse_returning_clause() do { auto expression = parse_expression(); - consume_if(TokenType::As); // 'AS' is optional. - String column_alias; - if (match(TokenType::Identifier)) - column_alias = consume().value(); + if (consume_if(TokenType::As) || match(TokenType::Identifier)) + column_alias = consume(TokenType::Identifier).value(); columns.append({ move(expression), move(column_alias) }); if (!match(TokenType::Comma)) @@ -860,11 +858,10 @@ NonnullRefPtr Parser::parse_result_column() auto expression = table_name.is_null() ? parse_expression() : static_cast>(*parse_column_name_expression(move(table_name), parsed_period)); - consume_if(TokenType::As); // 'AS' is optional. String column_alias; - if (match(TokenType::Identifier)) - column_alias = consume().value(); + if (consume_if(TokenType::As) || match(TokenType::Identifier)) + column_alias = consume(TokenType::Identifier).value(); return create_ast_node(move(expression), move(column_alias)); } @@ -884,11 +881,9 @@ NonnullRefPtr Parser::parse_table_or_subquery() table_name = move(schema_or_table_name); } - consume_if(TokenType::As); // 'AS' is optional. - String table_alias; - if (match(TokenType::Identifier)) - table_alias = consume().value(); + if (consume_if(TokenType::As) || match(TokenType::Identifier)) + table_alias = consume(TokenType::Identifier).value(); return create_ast_node(move(schema_name), move(table_name), move(table_alias)); } diff --git a/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp b/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp index c4c0fe36cb..7de8e45ed2 100644 --- a/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp +++ b/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp @@ -148,6 +148,8 @@ TEST_CASE(delete_) EXPECT(parse("DELETE FROM table WHERE 15").is_error()); EXPECT(parse("DELETE FROM table WHERE 15 RETURNING").is_error()); EXPECT(parse("DELETE FROM table WHERE 15 RETURNING *").is_error()); + EXPECT(parse("DELETE FROM table WHERE 15 RETURNING column").is_error()); + EXPECT(parse("DELETE FROM table WHERE 15 RETURNING column AS;").is_error()); EXPECT(parse("DELETE FROM table WHERE (');").is_error()); EXPECT(parse("WITH DELETE FROM table;").is_error()); EXPECT(parse("WITH table DELETE FROM table;").is_error()); @@ -243,6 +245,7 @@ TEST_CASE(select) EXPECT(parse("SELECT *").is_error()); EXPECT(parse("SELECT * FROM;").is_error()); EXPECT(parse("SELECT table. FROM table;").is_error()); + EXPECT(parse("SELECT column AS FROM table;").is_error()); EXPECT(parse("SELECT * FROM (").is_error()); EXPECT(parse("SELECT * FROM ()").is_error()); EXPECT(parse("SELECT * FROM ();").is_error()); @@ -250,6 +253,7 @@ TEST_CASE(select) EXPECT(parse("SELECT * FROM (table1, )").is_error()); EXPECT(parse("SELECT * FROM (table1, table2)").is_error()); EXPECT(parse("SELECT * FROM table").is_error()); + EXPECT(parse("SELECT * FROM table AS;").is_error()); EXPECT(parse("SELECT * FROM table WHERE;").is_error()); EXPECT(parse("SELECT * FROM table WHERE 1 ==1").is_error()); EXPECT(parse("SELECT * FROM table GROUP;").is_error()); -- cgit v1.2.3