From c369626ac19c4f03fb15e5d869c6c9d39ad56fa3 Mon Sep 17 00:00:00 2001 From: Jan de Visser Date: Sat, 13 Nov 2021 17:30:29 -0500 Subject: [PATCH] LibSQL: Gracefully react to unimplemented valid SQL Fixes a crash that was caused by a syntax error which is difficult to catch by the parser: usually identifiers are accepted in column lists, but they are not in a list of column values to be inserted in an INSERT. Fixed this by putting in a heuristic check; we probably need a better way to do this. Included tests for this case. Also introduced a new SQL Error code, `NotYetImplemented`, and return that instead of crashing when encountering unimplemented SQL. --- Tests/LibSQL/TestSqlStatementExecution.cpp | 22 ++++++++++++++++++++ Userland/Libraries/LibSQL/AST/Expression.cpp | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/Tests/LibSQL/TestSqlStatementExecution.cpp b/Tests/LibSQL/TestSqlStatementExecution.cpp index a96632c257..2cb23b0554 100644 --- a/Tests/LibSQL/TestSqlStatementExecution.cpp +++ b/Tests/LibSQL/TestSqlStatementExecution.cpp @@ -137,6 +137,28 @@ TEST_CASE(insert_wrong_number_of_values) EXPECT(result->inserted() == 0); } +TEST_CASE(insert_identifier_as_value) +{ + ScopeGuard guard([]() { unlink(db_name); }); + auto database = SQL::Database::construct(db_name); + EXPECT(!database->open().is_error()); + create_table(database); + auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ( identifier, 42 );"); + EXPECT(result->error().code == SQL::SQLErrorCode::SyntaxError); + EXPECT(result->inserted() == 0); +} + +TEST_CASE(insert_quoted_identifier_as_value) +{ + ScopeGuard guard([]() { unlink(db_name); }); + auto database = SQL::Database::construct(db_name); + EXPECT(!database->open().is_error()); + create_table(database); + auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ( \"QuotedIdentifier\", 42 );"); + EXPECT(result->error().code == SQL::SQLErrorCode::SyntaxError); + EXPECT(result->inserted() == 0); +} + TEST_CASE(insert_without_column_names) { ScopeGuard guard([]() { unlink(db_name); }); diff --git a/Userland/Libraries/LibSQL/AST/Expression.cpp b/Userland/Libraries/LibSQL/AST/Expression.cpp index d4030b3532..ce4c972e0c 100644 --- a/Userland/Libraries/LibSQL/AST/Expression.cpp +++ b/Userland/Libraries/LibSQL/AST/Expression.cpp @@ -169,6 +169,10 @@ Value UnaryOperatorExpression::evaluate(ExecutionContext& context) const Value ColumnNameExpression::evaluate(ExecutionContext& context) const { + if (!context.current_row) { + context.result->set_error(SQLErrorCode::SyntaxError, column_name()); + return Value::null(); + } auto& descriptor = *context.current_row->descriptor(); VERIFY(context.current_row->size() == descriptor.size()); Optional index_in_row;