Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIN() returns an interface{} #1965

Open
abh opened this issue Nov 23, 2022 · 4 comments
Open

MIN() returns an interface{} #1965

abh opened this issue Nov 23, 2022 · 4 comments

Comments

@abh
Copy link

abh commented Nov 23, 2022

Version

Other

What happened?

(version 1.16.0)

select min(id) from authors; creates a function that returns an interface{} instead of a NULL-able version of the id type.

#1574 talks about this for DATETIME types, but other issues indicates that it should work for simpler types, maybe?

If not, what's the workaround? Parsing the interface{} is awkward, best I can tell.

Relevant log output

No response

Database schema

No response

SQL queries

No response

Configuration

No response

Playground URL

https://play.sqlc.dev/p/96e9cf0291f2e13cc784144f8abd4d5a556c549f2bfe909a26377703f671ff61

What operating system are you using?

macOS

What database engines are you using?

MySQL

What type of code are you generating?

Go

@abh abh added bug Something isn't working triage New issues that hasn't been reviewed labels Nov 23, 2022
@d-tsuji
Copy link
Contributor

d-tsuji commented Nov 23, 2022

You can avoid this by casting a typecast. A PostgreSQL example is below.

-- name: GetMinID :one
select min(id)::BIGINT from authors;

Explicit typecasting will generate the intended code.

func (q *Queries) GetMinID(ctx context.Context) (int64, error) {
	row := q.db.QueryRowContext(ctx, getMinID)
	var column_1 int64
	err := row.Scan(&column_1)
	return column_1, err
}

In v1.16.0, aggregate functions such as MIN() and MAX() are not capable of generating fields of type depending on the column.

@abh
Copy link
Author

abh commented Dec 19, 2022

@d-tsuji I'm using MySQL for this project and the equivalent features (CAST(foo as BIGINT)) don't seem to be implemented.

@andrewmbenton
Copy link
Collaborator

andrewmbenton commented Jun 6, 2023

This is still an issue in v1.18.0: https://play.sqlc.dev/p/3931aa6d071068031e5eb03f4e40bd474d22afb2e47aabe0c34e68101e76d2f1.

There is already an issue open for adding CAST support: #687

@abh
Copy link
Author

abh commented Jul 18, 2023

It didn't work for my actual use case, but I noticed that in a simple use case doing a sub-select sometimes(?) makes sqlc figure out the correct type.

select id from (select min(id) from authors) as min_author;

https://play.sqlc.dev/p/e4b7f02a9c2ab5a4cea69f216758eb0d0a9ba42576804548e4f45b8c47e79910

kyleconroy pushed a commit that referenced this issue Jul 30, 2023
What is this

As the title said, this PR wants to add support for CAST function in MySQL.

This PR is based from PR by @ryanpbrewster here (which unfortunately he didn't send here, and only exist in his repository).
Why is this PR created

Currently sqlc unable to infer the correct type from SQL function like MAX, MIN, SUM, etc. For those function, sqlc will return its value as interface{}. This behavior can be seen in this playground.

As workaround, it advised to use CAST function to explicitly tell what is the type for that column, as mentioned in #1574.

Unfortunately, currently sqlc only support CAST function in PostgreSQL and not in MySQL. Thanks to this, right now MySQL users have to parse the interface{} manually, which is not really desirable.
What does this PR do?

    Implement convertFuncCast function for MySQL.
    Add better nil pointer check in some functions that related to convertFuncCast.

I haven't write any test because I'm not sure how and where to put it. However, as far as I know the code that handle ast.TypeCast for PostgreSQL also don't have any test, so I guess it's fine 🤷‍♂️
Related issues

Support CAST ... AS #687, which currently is the oldest MySQL issue that still opened.
Using MYSQL functions ( CONVERT and CAST) result in removing column from struct #1622
Unable to Type Alias #1866
sum in select result in model field type interface{} #1901
MIN() returns an interface{} #1965
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants