diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index 17eeefac8f..91a0f7bdb2 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -167,6 +167,7 @@ const skip_with_fsanitize_memory = [ 'vlib/orm/orm_option_time_test.v', 'vlib/db/sqlite/sqlite_test.v', 'vlib/db/sqlite/sqlite_orm_test.v', + 'vlib/db/sqlite/sqlite_comptime_field_test.v', 'vlib/db/sqlite/parent_child_test.v', 'vlib/db/sqlite/sqlite_vfs_lowlevel_test.v', 'vlib/v/tests/orm_enum_test.v', @@ -240,6 +241,7 @@ const skip_on_ubuntu_musl = [ 'vlib/net/http/status_test.v', 'vlib/db/sqlite/sqlite_test.v', 'vlib/db/sqlite/sqlite_orm_test.v', + 'vlib/db/sqlite/sqlite_comptime_field_test.v', 'vlib/db/sqlite/sqlite_vfs_lowlevel_test.v', 'vlib/db/sqlite/parent_child_test.v', 'vlib/orm/orm_test.v', diff --git a/vlib/db/sqlite/sqlite_comptime_field_test.v b/vlib/db/sqlite/sqlite_comptime_field_test.v new file mode 100644 index 0000000000..bbe5b33ae1 --- /dev/null +++ b/vlib/db/sqlite/sqlite_comptime_field_test.v @@ -0,0 +1,43 @@ +module main + +import db.sqlite + +@[table: 'blog'] +pub struct Blog { + id int @[primary; sql: serial] + slug string + language string +} + +fn records_by_field[T](db sqlite.DB, fieldname string, value string) ![]T { + $for field in T.fields { + if field.name == fieldname { + entries := sql db { + select from Blog where field.name == value + } or { return err } + return entries + } + } + return error('fieldname not found') +} + +fn test_main() { + db := sqlite.connect(':memory:')! + sql db { + create table Blog + }! + + row := Blog{ + slug: 'Test' + language: 'v' + } + + sql db { + insert row into Blog + }! + rows := records_by_field[Blog](db, 'language', 'v') or { + println(err) + return + } + assert rows.len == 1 +} diff --git a/vlib/v/checker/orm.v b/vlib/v/checker/orm.v index fb6b46622a..5ff3f26470 100644 --- a/vlib/v/checker/orm.v +++ b/vlib/v/checker/orm.v @@ -566,7 +566,8 @@ fn (mut c Checker) check_where_expr_has_no_pointless_exprs(table_type_symbol &as || expr.left is ast.PrefixExpr { c.check_where_expr_has_no_pointless_exprs(table_type_symbol, field_names, expr.left) - } else { + } else if !(expr.left is ast.SelectorExpr + && c.comptime.is_comptime_selector_field_name(expr.left, 'name')) { c.orm_error(has_no_field_error, expr.left.pos()) } diff --git a/vlib/v/gen/c/orm.v b/vlib/v/gen/c/orm.v index 4851cd983a..c3d441dc2c 100644 --- a/vlib/v/gen/c/orm.v +++ b/vlib/v/gen/c/orm.v @@ -809,7 +809,11 @@ fn (mut g Gen) write_orm_where_expr(expr ast.Expr, mut fields []string, mut pare data << expr } ast.SelectorExpr { - data << expr + if g.comptime.is_comptime_selector_field_name(expr, 'name') { + fields << g.comptime.comptime_for_field_value.name + } else { + data << expr + } } ast.BoolLiteral { data << expr