From fc15668415cc32e39a1896e262bd3cdac9d0d8c3 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 15:06:31 +0300 Subject: [PATCH] fmt: fix format line break for ORM update with multiline function (fixes #25883) --- vlib/v/fmt/fmt.v | 47 +++++++++++++++---- .../tests/orm_update_multiline_fn_expected.vv | 25 ++++++++++ .../tests/orm_update_multiline_fn_input.vv | 21 +++++++++ 3 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 vlib/v/fmt/tests/orm_update_multiline_fn_expected.vv create mode 100644 vlib/v/fmt/tests/orm_update_multiline_fn_input.vv diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index f7d4f724a..4e9b9bc41 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -1671,18 +1671,45 @@ pub fn (mut f Fmt) sql_stmt_line(node ast.SqlStmtLine) { f.writeln('insert ${node.object_var} into ${table_name}') } .update { - f.write('update ${table_name} set ') - for i, col in node.updated_columns { - f.write('${col} = ') - f.expr(node.update_exprs[i]) - if i < node.updated_columns.len - 1 { - f.write(', ') - } else { - f.write(' ') + mut has_multiline_update_expr := false + for expr in node.update_exprs { + if f.node_str(expr).contains('\n') { + has_multiline_update_expr = true + break + } + } + if has_multiline_update_expr { + f.writeln('update ${table_name} set') + // SQL block lines use a manual extra tab, so nested update values need two + // formatter indent levels to stay visually nested. + f.indent += 2 + for i, col in node.updated_columns { + f.write('${col} = ') + f.expr(node.update_exprs[i]) + if i < node.updated_columns.len - 1 { + f.write(',') + } + f.writeln('') } - f.wrap_long_line(3, true) + f.indent -= 2 + } else { + f.write('update ${table_name} set ') + for i, col in node.updated_columns { + f.write('${col} = ') + f.expr(node.update_exprs[i]) + if i < node.updated_columns.len - 1 { + f.write(', ') + } else { + f.write(' ') + } + f.wrap_long_line(3, true) + } + } + if has_multiline_update_expr { + f.write('\twhere ') + } else { + f.write('where ') } - f.write('where ') f.expr(node.where_expr) f.writeln('') } diff --git a/vlib/v/fmt/tests/orm_update_multiline_fn_expected.vv b/vlib/v/fmt/tests/orm_update_multiline_fn_expected.vv new file mode 100644 index 000000000..629a3bbdb --- /dev/null +++ b/vlib/v/fmt/tests/orm_update_multiline_fn_expected.vv @@ -0,0 +1,25 @@ +import db.sqlite + +struct User { + id string + name ?string + status u8 + hide u8 +} + +fn update(mut db sqlite.DB) { + req_status := true + req_hide := false + + sql db { + update User set + name = 'Jengro', + status = fn [req_status] () u8 { + return if req_status { u8(1) } else { u8(0) } + }(), + hide = fn [req_hide] () u8 { + return if req_hide { u8(1) } else { u8(0) } + }() + where id == '100' + } +} diff --git a/vlib/v/fmt/tests/orm_update_multiline_fn_input.vv b/vlib/v/fmt/tests/orm_update_multiline_fn_input.vv new file mode 100644 index 000000000..00a5ad577 --- /dev/null +++ b/vlib/v/fmt/tests/orm_update_multiline_fn_input.vv @@ -0,0 +1,21 @@ +import db.sqlite + +struct User { + id string + name ?string + status u8 + hide u8 +} + +fn update(mut db sqlite.DB) { + req_status := true + req_hide := false + + sql db { + update User set name = 'Jengro', status = fn [req_status] () u8 { + return if req_status { u8(1) } else { u8(0) } + }(), hide = fn [req_hide] () u8 { + return if req_hide { u8(1) } else { u8(0) } + }() where id == '100' + } +} -- 2.39.5