summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibSQL/AST.h16
-rw-r--r--Userland/Libraries/LibSQL/Parser.cpp5
-rw-r--r--Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp13
3 files changed, 33 insertions, 1 deletions
diff --git a/Userland/Libraries/LibSQL/AST.h b/Userland/Libraries/LibSQL/AST.h
index 96f0e970dc..fe8ff4d443 100644
--- a/Userland/Libraries/LibSQL/AST.h
+++ b/Userland/Libraries/LibSQL/AST.h
@@ -664,6 +664,15 @@ class ErrorStatement final : public Statement {
class CreateTable : public Statement {
public:
+ CreateTable(String schema_name, String table_name, RefPtr<Select> select_statement, bool is_temporary, bool is_error_if_table_exists)
+ : m_schema_name(move(schema_name))
+ , m_table_name(move(table_name))
+ , m_select_statement(move(select_statement))
+ , m_is_temporary(is_temporary)
+ , m_is_error_if_table_exists(is_error_if_table_exists)
+ {
+ }
+
CreateTable(String schema_name, String table_name, NonnullRefPtrVector<ColumnDefinition> columns, bool is_temporary, bool is_error_if_table_exists)
: m_schema_name(move(schema_name))
, m_table_name(move(table_name))
@@ -675,13 +684,20 @@ public:
const String& schema_name() const { return m_schema_name; }
const String& table_name() const { return m_table_name; }
+
+ bool has_selection() const { return !m_select_statement.is_null(); }
+ const RefPtr<Select>& select_statement() const { return m_select_statement; }
+
+ bool has_columns() const { return !m_columns.is_empty(); }
const NonnullRefPtrVector<ColumnDefinition> columns() const { return m_columns; }
+
bool is_temporary() const { return m_is_temporary; }
bool is_error_if_table_exists() const { return m_is_error_if_table_exists; }
private:
String m_schema_name;
String m_table_name;
+ RefPtr<Select> m_select_statement;
NonnullRefPtrVector<ColumnDefinition> m_columns;
bool m_is_temporary;
bool m_is_error_if_table_exists;
diff --git a/Userland/Libraries/LibSQL/Parser.cpp b/Userland/Libraries/LibSQL/Parser.cpp
index 8775c2d3b3..d1a7afda43 100644
--- a/Userland/Libraries/LibSQL/Parser.cpp
+++ b/Userland/Libraries/LibSQL/Parser.cpp
@@ -81,7 +81,10 @@ NonnullRefPtr<CreateTable> Parser::parse_create_table_statement()
String table_name;
parse_schema_and_table_name(schema_name, table_name);
- // FIXME: Parse "AS select-stmt".
+ if (consume_if(TokenType::As)) {
+ auto select_statement = parse_select_statement({});
+ return create_ast_node<CreateTable>(move(schema_name), move(table_name), move(select_statement), is_temporary, is_error_if_table_exists);
+ }
NonnullRefPtrVector<ColumnDefinition> column_definitions;
parse_comma_separated_list(true, [&]() { column_definitions.append(parse_column_definition()); });
diff --git a/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp b/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp
index 7de8e45ed2..06b4b5f82d 100644
--- a/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp
+++ b/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp
@@ -45,6 +45,8 @@ TEST_CASE(create_table)
EXPECT(parse("CREATE TABLE test ( column1 )").is_error());
EXPECT(parse("CREATE TABLE IF test ( column1 );").is_error());
EXPECT(parse("CREATE TABLE IF NOT test ( column1 );").is_error());
+ EXPECT(parse("CREATE TABLE AS;").is_error());
+ EXPECT(parse("CREATE TABLE AS SELECT;").is_error());
EXPECT(parse("CREATE TABLE test ( column1 varchar()").is_error());
EXPECT(parse("CREATE TABLE test ( column1 varchar(abc)").is_error());
EXPECT(parse("CREATE TABLE test ( column1 varchar(123 )").is_error());
@@ -55,6 +57,8 @@ TEST_CASE(create_table)
EXPECT(parse("CREATE TABLE test ( column1 varchar(0x) )").is_error());
EXPECT(parse("CREATE TABLE test ( column1 varchar(0xzzz) )").is_error());
EXPECT(parse("WITH table AS () CREATE TABLE test ( column1 );").is_error());
+ EXPECT(parse("CREATE TABLE test ( column1 int ) AS SELECT * FROM table;").is_error());
+ EXPECT(parse("CREATE TABLE test AS SELECT * FROM table ( column1 int ) ;").is_error());
struct Column {
StringView name;
@@ -75,6 +79,13 @@ TEST_CASE(create_table)
EXPECT_EQ(table.is_temporary(), expected_is_temporary);
EXPECT_EQ(table.is_error_if_table_exists(), expected_is_error_if_table_exists);
+ bool expect_select_statement = expected_columns.is_empty();
+ EXPECT_EQ(table.has_selection(), expect_select_statement);
+ EXPECT_EQ(table.has_columns(), !expect_select_statement);
+
+ const auto& select_statement = table.select_statement();
+ EXPECT_EQ(select_statement.is_null(), !expect_select_statement);
+
const auto& columns = table.columns();
EXPECT_EQ(columns.size(), expected_columns.size());
@@ -103,6 +114,8 @@ TEST_CASE(create_table)
validate("CREATE TEMPORARY TABLE test ( column1 );", {}, "test", { { "column1", "BLOB" } }, true, true);
validate("CREATE TABLE IF NOT EXISTS test ( column1 );", {}, "test", { { "column1", "BLOB" } }, false, false);
+ validate("CREATE TABLE test AS SELECT * FROM table;", {}, "test", {});
+
validate("CREATE TABLE test ( column1 int );", {}, "test", { { "column1", "int" } });
validate("CREATE TABLE test ( column1 varchar );", {}, "test", { { "column1", "varchar" } });
validate("CREATE TABLE test ( column1 varchar(255) );", {}, "test", { { "column1", "varchar", { 255 } } });