Skip to content

Commit f0fb86f

Browse files
authored
checker,orm: skip compile-time error msg for fields tagged with [skip] and [sql: '-'] (#18700)
1 parent 499d052 commit f0fb86f

File tree

5 files changed

+44
-31
lines changed

5 files changed

+44
-31
lines changed

vlib/orm/orm_test.v

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ struct Module {
1818

1919
[table: 'userlist']
2020
struct User {
21-
id int [primary; sql: serial]
21+
id int [primary; sql: serial]
2222
age int
23-
name string [sql: 'username']
23+
name string [sql: 'username']
2424
is_customer bool
25-
skipped_string string [skip]
26-
skipped_string2 string [sql: '-']
25+
skipped_string string [skip]
26+
skipped_string2 string [sql: '-']
27+
skipped_array []string [skip]
28+
skipped_array2 []string [sql: '-']
2729
}
2830

2931
struct Foo {
@@ -50,6 +52,8 @@ fn test_use_struct_field_as_limit() {
5052
age: 29
5153
name: 'Sam'
5254
skipped_string2: 'this should be ignored'
55+
skipped_array: ['ignored', 'array']
56+
skipped_array2: ['another', 'ignored', 'array']
5357
}
5458

5559
sql db {
@@ -65,6 +69,8 @@ fn test_use_struct_field_as_limit() {
6569
assert users[0].age == 29
6670
assert users[0].skipped_string == ''
6771
assert users[0].skipped_string2 == ''
72+
assert users[0].skipped_array == [], 'skipped because of the [skip] tag, used for both sql and json'
73+
assert users[0].skipped_array2 == [], "should be skipped, because of the sql specific [sql: '-'] tag"
6874
}
6975

7076
fn test_orm() {

vlib/v/ast/attr.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ pub fn (attrs []Attr) contains(str string) bool {
5454
return attrs.any(it.name == str)
5555
}
5656

57+
pub fn (attrs []Attr) contains_arg(str string, arg string) bool {
58+
return attrs.any(it.has_arg && it.name == str && it.arg == arg)
59+
}
60+
5761
[direct_array_access]
5862
pub fn (attrs []Attr) find_first(aname string) ?Attr {
5963
for a in attrs {

vlib/v/checker/orm.v

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -330,34 +330,37 @@ fn (mut c Checker) check_orm_struct_field_attributes(field ast.StructField) {
330330
}
331331

332332
fn (mut c Checker) fetch_and_verify_orm_fields(info ast.Struct, pos token.Pos, table_name string, sql_expr ast.SqlExpr) []ast.StructField {
333-
fields := info.fields.filter(fn [mut c] (field ast.StructField) bool {
334-
is_primitive := field.typ.is_string() || field.typ.is_bool() || field.typ.is_number()
335-
is_struct := c.table.type_symbols[int(field.typ)].kind == .struct_
336-
is_array := c.table.sym(field.typ).kind == .array
337-
is_array_with_struct_elements := is_array
338-
&& c.table.sym(c.table.sym(field.typ).array_info().elem_type).kind == .struct_
339-
has_no_skip_attr := !field.attrs.contains('skip')
340-
341-
return (is_primitive || is_struct || is_array_with_struct_elements) && has_no_skip_attr
342-
})
343-
344-
if fields.len == 0 {
345-
c.orm_error('select: empty fields in `${table_name}`', pos)
346-
return []ast.StructField{}
347-
}
348-
349333
field_pos := c.orm_get_field_pos(sql_expr.where_expr)
334+
mut fields := []ast.StructField{}
350335
for field in info.fields {
351-
if c.table.sym(field.typ).kind == .array
352-
&& c.table.sym(c.table.sym(field.typ).array_info().elem_type).is_primitive() {
336+
is_primitive := field.typ.is_string() || field.typ.is_bool() || field.typ.is_number()
337+
fsym := c.table.sym(field.typ)
338+
is_struct := fsym.kind == .struct_
339+
is_array := fsym.kind == .array
340+
elem_sym := if is_array {
341+
c.table.sym(fsym.array_info().elem_type)
342+
} else {
343+
ast.invalid_type_symbol
344+
}
345+
is_array_with_struct_elements := is_array && elem_sym.kind == .struct_
346+
has_skip_attr := field.attrs.contains('skip') || field.attrs.contains_arg('sql', '-')
347+
if has_skip_attr {
348+
continue
349+
}
350+
if is_primitive || is_struct || is_array_with_struct_elements {
351+
fields << field
352+
}
353+
if is_array && elem_sym.is_primitive() {
353354
c.add_error_detail('')
354355
c.add_error_detail(' field name: `${field.name}`')
355356
c.add_error_detail(' data type: `${c.table.type_to_str(field.typ)}`')
356357
c.orm_error('does not support array of primitive types', field_pos)
357358
return []ast.StructField{}
358359
}
359360
}
360-
361+
if fields.len == 0 {
362+
c.orm_error('select: empty fields in `${table_name}`', pos)
363+
}
361364
return fields
362365
}
363366

vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.vv:15:29: erro
55
| ~~~~~~~
66
16 | }!
77
17 | f := sql db {
8-
Details:
8+
Details:
99
field name: `example`
1010
data type: `[]u8`
11-
vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.vv:18:34: error: V ORM: does not support array of primitive types
11+
vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.vv:18:30: error: V ORM: does not support array of primitive types
1212
16 | }!
1313
17 | f := sql db {
14-
18 | select from Example where (example == bytes)
15-
| ~~~~~~~
16-
19 | }!
14+
18 | select from Example where (example == bytes)
15+
| ~~~~~~~
16+
19 | }!
1717
20 | print(e)
18-
Details:
18+
Details:
1919
field name: `example`
2020
data type: `[]u8`

vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.vv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ fn main() {
1515
select from Example where example == bytes
1616
}!
1717
f := sql db {
18-
select from Example where (example == bytes)
19-
}!
18+
select from Example where (example == bytes)
19+
}!
2020
print(e)
2121
print(f)
2222
}

0 commit comments

Comments
 (0)