1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 19:27:35 +00:00

LibSQL: Parse DROP TABLE statement

This commit is contained in:
Timothy Flynn 2021-04-20 10:16:28 -04:00 committed by Andreas Kling
parent 110cd98c0a
commit e92bffb2e3
4 changed files with 79 additions and 2 deletions

View file

@ -125,4 +125,23 @@ private:
bool m_is_error_if_table_exists;
};
class DropTable : public Statement {
public:
DropTable(String schema_name, String table_name, bool is_error_if_table_does_not_exist)
: m_schema_name(move(schema_name))
, m_table_name(move(table_name))
, m_is_error_if_table_does_not_exist(is_error_if_table_does_not_exist)
{
}
const String& schema_name() const { return m_schema_name; }
const String& table_name() const { return m_table_name; }
bool is_error_if_table_does_not_exist() const { return m_is_error_if_table_does_not_exist; }
private:
String m_schema_name;
String m_table_name;
bool m_is_error_if_table_does_not_exist;
};
}

View file

@ -38,8 +38,10 @@ NonnullRefPtr<Statement> Parser::next_statement()
switch (m_parser_state.m_token.type()) {
case TokenType::Create:
return parse_create_table_statement();
case TokenType::Drop:
return parse_drop_table_statement();
default:
expected("CREATE");
expected("CREATE or DROP");
return create_ast_node<ErrorStatement>();
}
}
@ -98,6 +100,36 @@ NonnullRefPtr<CreateTable> Parser::parse_create_table_statement()
return create_ast_node<CreateTable>(move(schema_name), move(table_name), move(column_definitions), is_temporary, is_error_if_table_exists);
}
NonnullRefPtr<DropTable> Parser::parse_drop_table_statement()
{
// https://sqlite.org/lang_droptable.html
consume(TokenType::Drop);
consume(TokenType::Table);
bool is_error_if_table_does_not_exist = true;
if (match(TokenType::If)) {
consume(TokenType::If);
consume(TokenType::Exists);
is_error_if_table_does_not_exist = false;
}
String schema_or_table_name = consume(TokenType::Identifier).value();
String schema_name;
String table_name;
if (match(TokenType::Period)) {
consume();
schema_name = move(schema_or_table_name);
table_name = consume(TokenType::Identifier).value();
} else {
table_name = move(schema_or_table_name);
}
consume(TokenType::SemiColon);
return create_ast_node<DropTable>(move(schema_name), move(table_name), is_error_if_table_does_not_exist);
}
NonnullRefPtr<ColumnDefinition> Parser::parse_column_definition()
{
// https://sqlite.org/syntax/column-def.html

View file

@ -67,8 +67,9 @@ private:
Vector<Error> m_errors;
};
NonnullRefPtr<ColumnDefinition> parse_column_definition();
NonnullRefPtr<CreateTable> parse_create_table_statement();
NonnullRefPtr<DropTable> parse_drop_table_statement();
NonnullRefPtr<ColumnDefinition> parse_column_definition();
NonnullRefPtr<TypeName> parse_type_name();
NonnullRefPtr<SignedNumber> parse_signed_number();

View file

@ -132,4 +132,29 @@ TEST_CASE(create_table)
validate("CREATE TABLE test ( column1 varchar(1e3) );", {}, "test", { { "column1", "varchar", { 1000 } } });
}
TEST_CASE(drop_table)
{
EXPECT(parse("DROP").is_error());
EXPECT(parse("DROP TABLE").is_error());
EXPECT(parse("DROP TABLE test").is_error());
EXPECT(parse("DROP TABLE IF test;").is_error());
auto validate = [](StringView sql, StringView expected_schema, StringView expected_table, bool expected_is_error_if_table_does_not_exist = true) {
auto result = parse(sql);
EXPECT(!result.is_error());
auto statement = result.release_value();
EXPECT(is<SQL::DropTable>(*statement));
const auto& table = static_cast<const SQL::DropTable&>(*statement);
EXPECT_EQ(table.schema_name(), expected_schema);
EXPECT_EQ(table.table_name(), expected_table);
EXPECT_EQ(table.is_error_if_table_does_not_exist(), expected_is_error_if_table_does_not_exist);
};
validate("DROP TABLE test;", {}, "test");
validate("DROP TABLE schema.test;", "schema", "test");
validate("DROP TABLE IF EXISTS test;", {}, "test", false);
}
TEST_MAIN(SqlParser)