Skip to content

Commit

Permalink
orm: fix cgen inserting wrong array index (#19324)
Browse files Browse the repository at this point in the history
  • Loading branch information
Casper64 committed Sep 12, 2023
1 parent 55ca8d8 commit e8d133d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
2 changes: 2 additions & 0 deletions cmd/tools/vtest-self.v
Expand Up @@ -134,6 +134,7 @@ const (
'vlib/orm/orm_mut_db_test.v',
'vlib/orm/orm_result_test.v',
'vlib/orm/orm_custom_operators_test.v',
'vlib/orm/orm_fk_test.v',
'vlib/db/sqlite/sqlite_test.v',
'vlib/db/sqlite/sqlite_orm_test.v',
'vlib/db/sqlite/sqlite_vfs_lowlevel_test.v',
Expand Down Expand Up @@ -213,6 +214,7 @@ const (
'vlib/orm/orm_mut_db_test.v',
'vlib/orm/orm_result_test.v',
'vlib/orm/orm_custom_operators_test.v',
'vlib/orm/orm_fk_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/orm_sub_array_struct_test.v',
'vlib/v/tests/orm_joined_tables_select_test.v',
Expand Down
57 changes: 57 additions & 0 deletions vlib/orm/orm_fk_test.v
@@ -0,0 +1,57 @@
import db.sqlite

struct Person {
id int [primary; sql: serial]
age int
brothers []Brother [fkey: 'person_id']
sisters []Sister [fkey: 'person_id']
field_after_fkeys string
}

struct Brother {
id int [primary; sql: serial]
person_id int
name string
}

struct Sister {
id int [primary; sql: serial]
person_id int
name string
}

fn test_field_after_fkeys() {
db := sqlite.connect(':memory:') or { panic(err) }

sql db {
create table Brother
create table Sister
create table Person
}!

person := Person{
age: 21
brothers: [Brother{
name: 'aaa'
}, Brother{
name: 'bbb'
}]
sisters: [Sister{
name: 'ccc'
}, Sister{
name: 'ddd'
}]
field_after_fkeys: 'eee'
}

sql db {
insert person into Person
}!

persons := sql db {
select from Person
}!

assert persons[0].age == 21
assert persons[0].field_after_fkeys == 'eee'
}
8 changes: 6 additions & 2 deletions vlib/v/gen/c/orm.v
Expand Up @@ -876,8 +876,10 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, le

g.writeln('if (${select_unwrapped_result_var_name}.len > 0) {')
g.indent++
for i, field in fields {
array_get_call_code := '(*(orm__Primitive*) array_get((*(Array_orm__Primitive*) array_get(${select_unwrapped_result_var_name}, ${idx})), ${i}))'

mut selected_fields_idx := 0
for field in fields {
array_get_call_code := '(*(orm__Primitive*) array_get((*(Array_orm__Primitive*) array_get(${select_unwrapped_result_var_name}, ${idx})), ${selected_fields_idx}))'
sym := g.table.sym(field.typ)
if sym.kind == .struct_ && sym.name != 'time.Time' {
mut sub := node.sub_structs[int(field.typ)]
Expand All @@ -897,6 +899,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, le

g.write_orm_select(sub, connection_var_name, '${tmp}.${c_name(field.name)} = ',
or_expr)
selected_fields_idx++
} else if sym.kind == .array {
mut fkey := ''
// TODO: move to the ORM checker
Expand Down Expand Up @@ -956,6 +959,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, le
} else {
mut typ := sym.cname
g.writeln('${tmp}.${c_name(field.name)} = *(${array_get_call_code}._${typ});')
selected_fields_idx++
}
}
g.indent--
Expand Down

0 comments on commit e8d133d

Please sign in to comment.