1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker,orm: add compile error for unsupported field data types like field []int etc (#18537)

This commit is contained in:
Swastik Baranwal 2023-06-28 16:10:36 +05:30 committed by GitHub
parent 2b2aca6eb7
commit 499d0526fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 3 deletions

View File

@ -40,7 +40,8 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
}
info := table_sym.info as ast.Struct
mut fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name)
mut fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name,
node)
non_primitive_fields := c.get_orm_non_primitive_fields(fields)
mut sub_structs := map[int]ast.SqlExpr{}
@ -215,7 +216,8 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
}
info := table_sym.info as ast.Struct
mut fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name)
mut fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name,
ast.SqlExpr{})
mut sub_structs := map[int]ast.SqlStmtLine{}
non_primitive_fields := c.get_orm_non_primitive_fields(fields)
@ -327,7 +329,7 @@ fn (mut c Checker) check_orm_struct_field_attributes(field ast.StructField) {
}
}
fn (mut c Checker) fetch_and_verify_orm_fields(info ast.Struct, pos token.Pos, table_name string) []ast.StructField {
fn (mut c Checker) fetch_and_verify_orm_fields(info ast.Struct, pos token.Pos, table_name string, sql_expr ast.SqlExpr) []ast.StructField {
fields := info.fields.filter(fn [mut c] (field ast.StructField) bool {
is_primitive := field.typ.is_string() || field.typ.is_bool() || field.typ.is_number()
is_struct := c.table.type_symbols[int(field.typ)].kind == .struct_
@ -344,6 +346,18 @@ fn (mut c Checker) fetch_and_verify_orm_fields(info ast.Struct, pos token.Pos, t
return []ast.StructField{}
}
field_pos := c.orm_get_field_pos(sql_expr.where_expr)
for field in info.fields {
if c.table.sym(field.typ).kind == .array
&& c.table.sym(c.table.sym(field.typ).array_info().elem_type).is_primitive() {
c.add_error_detail('')
c.add_error_detail(' field name: `${field.name}`')
c.add_error_detail(' data type: `${c.table.type_to_str(field.typ)}`')
c.orm_error('does not support array of primitive types', field_pos)
return []ast.StructField{}
}
}
return fields
}
@ -610,3 +624,24 @@ fn (_ &Checker) check_field_of_inserting_struct_is_uninitialized(node &ast.SqlSt
return false
}
fn (c &Checker) orm_get_field_pos(expr &ast.Expr) token.Pos {
mut pos := token.Pos{}
if expr is ast.InfixExpr {
if expr.left is ast.Ident {
pos = expr.left.pos
} else if expr.left is ast.InfixExpr || expr.left is ast.ParExpr
|| expr.left is ast.PrefixExpr {
pos = c.orm_get_field_pos(expr.left)
} else {
pos = expr.left.pos()
}
} else if expr is ast.ParExpr {
pos = c.orm_get_field_pos(expr.expr)
} else if expr is ast.PrefixExpr {
pos = c.orm_get_field_pos(expr.right)
} else {
pos = expr.pos()
}
return pos
}

View File

@ -0,0 +1,20 @@
vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.vv:15:29: error: V ORM: does not support array of primitive types
13 | bytes := [u8(0)]
14 | e := sql db {
15 | select from Example where example == bytes
| ~~~~~~~
16 | }!
17 | f := sql db {
Details:
field name: `example`
data type: `[]u8`
vlib/v/checker/tests/orm_where_clause_unsupported_field_types_err.vv:18:34: error: V ORM: does not support array of primitive types
16 | }!
17 | f := sql db {
18 | select from Example where (example == bytes)
| ~~~~~~~
19 | }!
20 | print(e)
Details:
field name: `example`
data type: `[]u8`

View File

@ -0,0 +1,22 @@
module main
import db.pg
[table: 'example']
pub struct Example {
id int [primary; sql: serial]
example []u8 [sql_type: 'bytea'; unique]
}
fn main() {
db := pg.connect(pg.Config{}) or { exit(0) }
bytes := [u8(0)]
e := sql db {
select from Example where example == bytes
}!
f := sql db {
select from Example where (example == bytes)
}!
print(e)
print(f)
}