-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
database/sql: add support to explicitly set input parameter types and result column types #12383
Comments
Do you have any examples of 1)? IMHO a driver should care of converting to the right database representation. Could it be a bug in the driver? Maybe the solution for this is to provide a standard interface for querying table metadata (list of columns with their types)? Should database specific types be provided by the driver package? Not every database has all the types and sometimes they are different between databases (or even different versions of the same database). |
@kostya-sh I address the issue of types in this description. I even have an implementation that shows this works. I don't want table meta-data, nor do I wish for separate API to get that meta-data. If you're talking CRUD queries, that might be fine. I'm talking about larger queries that do business logic and the queries types aren't necessarily represented in any table anywhere. |
In case of PostgreSQL it seems that specifying types for parameters is redundant as the database itself provides this information to the dirver (based on the source of |
@kostya-sh You are correct. Prepared statements infer types and send those back to the client. As such you probably wouldn't utilize this in that case. Also postgresql text is compatible with varchar, unlike other systems where it maters. Now I shall get all my clients and client's vendors to use postgresql and we'll be set... |
@kardianos, I wasn't suggesting to switch all your clients to PostgreSQL ;) My intention was to collect use cases that are not possible to implement correctly withput specifying parameter types. After a bit more digging I found that there are cases when PostgreSQL cannot infer parameter types. For example the following SQL cannot be currently executed using
This is because there are two |
I think is better leave input parameter types to database drivers as they vary among different database venders. We could also create a The problem here is that we can't really pass custom types to The solution is let the custom types in database drivers implement the For output types, if needed, it could implement the |
The interface added in type InputValue interface {
Validate() bool
} Then |
@bradfitz Could you write why the |
I think they were meant for drivers to use for validation. Or maybe it was an internal detail and we didn't have internal packages at the time. I forget. You can update the docs on it. |
@bradfitz I would actually prefer to remove the sql/driver uses of it, and request drivers use it to validate their own types. At least, I think that would be one of the required types to support custom database types. I just don't see the value of this call. If the driver doesn't support the parameter input type, let the driver throw the error. The second option would be to add a new interface for the driver.Stmt, interface would be in charge of calling IsValid after checking custom driver types. So we could retain the current behavior until the driver adds the checks themselves. No POC yet. Thoughts? |
Well, the idea was we wanted to make it easier to write drivers and not require drivers to deal with every one of Go's integer type sizes and signedness. That's why there's only So we still want to convert the common things (like |
Right now database/sql infers input parameter types and omits database column level types,
This can be hard to support do to each database vendor supporting different types or different variants of types, however I believe a practical solution exists.
There are two parts to this (1) support setting input parameter types and (2) fetching result column types.
For example Oracle has both "varchar(N), varchar2(N), and char(N) data types. In greenfield work you will probably work with and use varchar2(N) type. Legacy systems may have any of those. For each one of those setting the length of the parameter can be, though is not always, meaningful.
In MS SQL Server there are several different time types as well as text types: You may need a Time, Date, DateTime, DateTime2, or DateTimeOffset. For text you may need a text, ntext, char(N), varchar(N), or nvarchar(N) type. Some of the data types, such as "ntext" vs "nvarchar(N)" or DateTime2 vs DateTimeOffset are important and impossible to auto-discover.
...
For types I recommend a two tier approach: have a set of common types defined: sql.Text, sql.Timestamp, sql.Timestampz, sql.Int, sql.Decimal, sql.Float, but allow drivers to also register types like: or.Varchar2, ms.Nvarchar, pg.Array.
The driver then documents how the sql generic types map onto the database types. Most often the generic types can be used (or simply inferred), but when the a specific type is needed it is only a quick parameter set away. I have implemented something like this and I am pleased with the result.
The text was updated successfully, but these errors were encountered: