Skip to content

Commit 4e2ba51

Browse files
committed
feat: infer parameter types from function call return types in comparison expressions.
1 parent ce83d3f commit 4e2ba51

File tree

7 files changed

+152
-0
lines changed

7 files changed

+152
-0
lines changed

internal/compiler/resolve.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,36 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
142142
})
143143

144144
case *ast.A_Expr:
145+
// If one side of the comparison is a direct FuncCall, use the
146+
// function's return type for the parameter. This prevents the
147+
// ColumnRef search below from descending into the function's
148+
// arguments and incorrectly using a nested column's type
149+
// (e.g. DATEDIFF(date_from, NOW()) >= ? should yield int, not date).
150+
var funcCallSide *ast.FuncCall
151+
if fc, ok := n.Lexpr.(*ast.FuncCall); ok {
152+
funcCallSide = fc
153+
} else if fc, ok := n.Rexpr.(*ast.FuncCall); ok {
154+
funcCallSide = fc
155+
}
156+
if funcCallSide != nil {
157+
fun, ferr := c.ResolveFuncCall(funcCallSide)
158+
if ferr == nil && fun.ReturnType != nil && fun.ReturnType.Name != "any" {
159+
defaultP := named.NewInferredParam(ref.name, true)
160+
p, isNamed := params.FetchMerge(ref.ref.Number, defaultP)
161+
a = append(a, Parameter{
162+
Number: ref.ref.Number,
163+
Column: &Column{
164+
Name: p.Name(),
165+
DataType: dataType(fun.ReturnType),
166+
NotNull: p.NotNull(),
167+
IsNamedParam: isNamed,
168+
IsSqlcSlice: p.IsSqlcSlice(),
169+
},
170+
})
171+
continue
172+
}
173+
}
174+
145175
// TODO: While this works for a wide range of simple expressions,
146176
// more complicated expressions will cause this logic to fail.
147177
list := astutils.Search(n.Lexpr, func(node ast.Node) bool {

internal/endtoend/testdata/mysql_datediff_type/mysql/db.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/mysql_datediff_type/mysql/models.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/mysql_datediff_type/mysql/query.sql.go

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- name: GetUpdateableWishlistItemIDs :many
2+
SELECT id
3+
FROM wishlist_item
4+
WHERE DATEDIFF(date_from, NOW()) >= sqlc.arg('min_days_to_date_from')
5+
AND DATEDIFF(date_from, NOW()) <= sqlc.arg('max_days_to_date_from')
6+
AND updated_at < sqlc.arg('updated_by');
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE wishlist_item (
2+
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
3+
date_from DATE NOT NULL,
4+
updated_at TIMESTAMP NULL DEFAULT NULL
5+
);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"version": "2",
3+
"sql": [
4+
{
5+
"engine": "mysql",
6+
"queries": "query.sql",
7+
"schema": "schema.sql",
8+
"gen": {
9+
"go": {
10+
"package": "mysql_datediff_type",
11+
"out": "mysql"
12+
}
13+
}
14+
}
15+
]
16+
}

0 commit comments

Comments
 (0)