Coverage Report

Created: 2025-09-05 06:52

/src/serenity/Userland/Libraries/LibSQL/AST/Update.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <LibSQL/AST/AST.h>
8
#include <LibSQL/Database.h>
9
#include <LibSQL/Meta.h>
10
#include <LibSQL/Row.h>
11
12
namespace SQL::AST {
13
14
ResultOr<ResultSet> Update::execute(ExecutionContext& context) const
15
0
{
16
0
    auto const& schema_name = m_qualified_table_name->schema_name();
17
0
    auto const& table_name = m_qualified_table_name->table_name();
18
0
    auto table_def = TRY(context.database->get_table(schema_name, table_name));
19
20
0
    Vector<Row> matched_rows;
21
22
0
    for (auto& table_row : TRY(context.database->select_all(*table_def))) {
23
0
        context.current_row = &table_row;
24
25
0
        if (auto const& where_clause = this->where_clause()) {
26
0
            auto where_result = TRY(where_clause->evaluate(context)).to_bool();
27
0
            if (!where_result.has_value() || !where_result.value())
28
0
                continue;
29
0
        }
30
31
0
        TRY(matched_rows.try_append(move(table_row)));
32
0
    }
33
34
0
    ResultSet result { SQLCommand::Update };
35
36
0
    for (auto& update_column : m_update_columns) {
37
0
        auto row_value = TRY(update_column.expression->evaluate(context));
38
39
0
        for (auto& table_row : matched_rows) {
40
0
            auto& row_descriptor = *table_row.descriptor();
41
42
0
            for (auto const& column_name : update_column.column_names) {
43
0
                if (!table_row.has(column_name))
44
0
                    return Result { SQLCommand::Update, SQLErrorCode::ColumnDoesNotExist, column_name };
45
46
0
                auto column_index = row_descriptor.find_if([&](auto element) { return element.name == column_name; }).index();
47
0
                auto column_type = row_descriptor[column_index].type;
48
49
0
                if (!row_value.is_type_compatible_with(column_type))
50
0
                    return Result { SQLCommand::Update, SQLErrorCode::InvalidValueType, column_name };
51
52
0
                table_row[column_index] = row_value;
53
0
            }
54
55
0
            TRY(context.database->update(table_row));
56
0
            result.insert_row(table_row, {});
57
0
        }
58
0
    }
59
60
0
    return result;
61
0
}
62
63
}