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

sum in select result in model field type interface{} #1901

Open
sosolyht opened this issue Oct 17, 2022 · 5 comments
Open

sum in select result in model field type interface{} #1901

sosolyht opened this issue Oct 17, 2022 · 5 comments

Comments

@sosolyht
Copy link

sosolyht commented Oct 17, 2022

Version

1.14.0

What happened?

Hello, I found an error while using sqlc and mysql

return value must be int64

but it's an interface .

need cast to int64

const totalVAT = `-- name: TotalVAT :one
SELECT sum(vat) as vatpence
FROM sales
`

func (q *Queries) TotalVAT(ctx context.Context) (interface{}, error) {
	row := q.db.QueryRowContext(ctx, totalVAT)
	var vatpence interface{}
	err := row.Scan(&vatpence)
	return vatpence, err
}

Relevant log output

No response

Database schema

CREATE TABLE sales (
  vat integer      NOT NULL
);

SQL queries

-- name: TotalVAT :one
SELECT sum(vat) as vatpence
FROM sales;

Configuration

No response

Playground URL

https://play.sqlc.dev/p/6552b583f39af63c0d407f76b62cafdfe471b130c76d9066b9843b8c20b8cd90

What operating system are you using?

macOS

What database engines are you using?

MySQL

What type of code are you generating?

Go

@sosolyht sosolyht added bug Something isn't working triage New issues that hasn't been reviewed labels Oct 17, 2022
@brlala
Copy link

brlala commented Oct 18, 2022

use this as a workaround

SELECT sum(vat) :: integer as vatpence
FROM sales

@sosolyht
Copy link
Author

@brlala thank you, but this solution does not work with mysql

@sosolyht
Copy link
Author

func convertInterfaceToInt64(t interface{}) (int64, error) {
	switch t := t.(type) {
	case int64:
		return t, nil
	case int:
		return int64(t), nil
	case string:
		return strconv.ParseInt(t, 10, 64)
	case []byte:
		return strconv.ParseInt(string(t), 10, 64)
	default:
		return 0, fmt.Errorf("type %T not supported", t)
	}
}

query is return from interface to byte type

so we can solve this problem

@kyleconroy kyleconroy added 💻 darwin 📚 mysql 🔧 golang and removed triage New issues that hasn't been reviewed labels Nov 9, 2022
@abh
Copy link

abh commented Dec 19, 2022

Related to #1622

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
@andrewmbenton
Copy link
Collaborator

use this as a workaround

SELECT sum(vat) :: integer as vatpence
FROM sales

As noted, this workaround doesn't work for MySQL. The following does work though:

SELECT CAST(sum(vat) AS unsigned) vatpence
FROM sales;

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

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

5 participants