From 690f84559442b278fdb280a273a7cfe5f39ea117 Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sun, 30 Mar 2025 20:26:16 +0800 Subject: [PATCH] cgen: fix nested array support for the orm (fix #19327) (#24080) --- cmd/tools/vtest-self.v | 2 + vlib/orm/orm_nested_struct_test.v | 133 ++++++++++++++++++++++++++++++ vlib/v/gen/c/orm.v | 2 +- 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 vlib/orm/orm_nested_struct_test.v diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index 1e8551981e..c7d00dd018 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -149,6 +149,7 @@ const skip_with_fsanitize_memory = [ 'vlib/orm/orm_result_test.v', 'vlib/orm/orm_custom_operators_test.v', 'vlib/orm/orm_fk_test.v', + 'vlib/orm/orm_nested_struct_test.v', 'vlib/orm/orm_references_test.v', 'vlib/orm/orm_option_array_test.v', 'vlib/orm/orm_option_time_test.v', @@ -238,6 +239,7 @@ const skip_on_ubuntu_musl = [ 'vlib/orm/orm_result_test.v', 'vlib/orm/orm_custom_operators_test.v', 'vlib/orm/orm_fk_test.v', + 'vlib/orm/orm_nested_struct_test.v', 'vlib/orm/orm_references_test.v', 'vlib/orm/orm_option_array_test.v', 'vlib/orm/orm_option_time_test.v', diff --git a/vlib/orm/orm_nested_struct_test.v b/vlib/orm/orm_nested_struct_test.v new file mode 100644 index 0000000000..7f93338ff9 --- /dev/null +++ b/vlib/orm/orm_nested_struct_test.v @@ -0,0 +1,133 @@ +// vtest flaky: true +// vtest retry: 3 +import db.sqlite + +struct Address { + id int @[primary; sql: serial] + parent_id int + create_at string + update_at string + street string + city string + state string + zip_code string + proximity string +} + +@[table: 'RealStates'] +struct RealState { + id string @[primary; sql_type: 'uuid'] + parent_id int + name string @[sql_type: 'varchar(80)'] + cnpj string @[sql_type: 'varchar(14)'] + address []Address @[fkey: 'parent_id'] +} + +@[table: 'Realtors'] +struct Realtor { + id ?string @[primary; sql_type: 'uuid'] + first_name string @[sql_type: 'VARCHAR(30)'] + last_name string @[sql_type: 'VARCHAR(30)'] + creci string @[sql_type: 'VARCHAR(8)'] + cnpj ?string @[sql_type: 'VARCHAR(15)'] + cpf ?string @[sql_type: 'VARCHAR(12)'] + phone string @[sql_type: 'VARCHAR(15)'] + real_state RealState @[fkey: 'id'] +} + +fn test_orm_nested_struct() { + mut db := sqlite.connect(':memory:')! + + data := Realtor{ + first_name: 'John' + last_name: 'Doe' + creci: '12345678' + cnpj: '12345678901234' + cpf: '12345678901' + phone: '1234567890' + real_state: RealState{ + name: 'Teste' + cnpj: '12345678901234' + address: [ + Address{ + street: 'Teste' + city: 'Teste' + state: 'Teste' + zip_code: 'Teste' + proximity: 'Teste' + }, + ] + } + } + + sql db { + create table Address + create table RealState + create table Realtor + }! + + sql db { + insert data into Realtor + }! + + x1 := sql db { + select from Address + }! + assert x1.str() == "[Address{ + id: 1 + parent_id: 0 + create_at: '' + update_at: '' + street: 'Teste' + city: 'Teste' + state: 'Teste' + zip_code: 'Teste' + proximity: 'Teste' +}]" + + x2 := sql db { + select from RealState + }! + assert x2.str() == "[RealState{ + id: '' + parent_id: 0 + name: 'Teste' + cnpj: '12345678901234' + address: [Address{ + id: 1 + parent_id: 0 + create_at: '' + update_at: '' + street: 'Teste' + city: 'Teste' + state: 'Teste' + zip_code: 'Teste' + proximity: 'Teste' + }] +}]" + + x3 := sql db { + select from Realtor + }! + + // FIXME! + // I think this result is not correct. + assert x3.str() == "[Realtor{ + id: Option(none) + first_name: 'John' + last_name: 'Doe' + creci: '12345678' + cnpj: Option('12345678901234') + cpf: Option('12345678901') + phone: '1234567890' + real_state: RealState{ + id: '' + parent_id: 0 + name: '' + cnpj: '' + address: [] + } +}]" + + db.close()! +} diff --git a/vlib/v/gen/c/orm.v b/vlib/v/gen/c/orm.v index eb324738fa..034ffd7aac 100644 --- a/vlib/v/gen/c/orm.v +++ b/vlib/v/gen/c/orm.v @@ -1140,7 +1140,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re g.writeln('\t${field_var}.state = 0;') g.writeln('\t*(${g.base_type(field.typ)}*)${field_var}.data = *(${g.base_type(field.typ)}*)${sub_result_var}.data;') } else { - g.writeln('\t${field_var} = *(${unwrapped_c_typ}*)${sub_result_var}.data;') + g.writeln('\t${field_var} = *(${g.base_type(field.typ)}*)${sub_result_var}.data;') } g.writeln('}') }