checker: fix orm bug, when a joined table field context replaced the original table field context

master
Delyan Angelov 2022-05-17 11:39:53 +03:00
parent 02c8a6057c
commit 78ab3296c9
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 45 additions and 0 deletions

View File

@ -12,7 +12,11 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
}
sym := c.table.sym(node.table_expr.typ)
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
old_ts := c.cur_orm_ts
c.cur_orm_ts = *sym
defer {
c.cur_orm_ts = old_ts
}
if sym.info !is ast.Struct {
c.error('The table symbol `$sym.name` has to be a struct', node.table_expr.pos)
return ast.void_type
@ -114,7 +118,11 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
}
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
table_sym := c.table.sym(node.table_expr.typ)
old_ts := c.cur_orm_ts
c.cur_orm_ts = *table_sym
defer {
c.cur_orm_ts = old_ts
}
if table_sym.info !is ast.Struct {
c.error('unknown type `$table_sym.name`', node.pos)
return ast.void_type

View File

@ -0,0 +1,37 @@
import sqlite
struct VieterDb {
conn sqlite.DB
}
pub struct GitRepoArch {
pub:
id int [primary; sql: serial]
repo_id int [nonull]
// repo string
value string [nonull]
}
pub struct GitRepo {
pub mut:
id int [optional; primary; sql: serial]
repo string [nonull]
arch []GitRepoArch [fkey: 'repo_id']
}
pub fn (db &VieterDb) get_git_repos() []GitRepo {
// NB: the query here, uses the `repo` field on GitRepo,
// while GitRepo is joined to GitRepoArch,
// which does *not* have a `repo` field.
// When this test was added, the checker used `GitRepoArch`
// to check for `repo`'s presence (which is wrong), because of
// a lingering c.cur_orm_ts state. The fix was to save/restore c.cur_orm_ts .
res := sql db.conn {
select from GitRepo where repo == 'something' order by id
}
return res
}
fn test_compiles() {
assert true
}