-
Notifications
You must be signed in to change notification settings - Fork 913
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
Support Postgresql array types #302
Conversation
I think the first thing here would be to split this into two separate patches, unless there's a really good reason not to. These two seem to be entirely separate functionality, and conflating them makes for a tough review process.
I'm guessing this is because of the comment I made in #49 in February? Prepared statements are quite evil so I'd like to avoid this limitation if possible; or at least provide a workaround, if nothing else. It's not clear how my suggestion in #49 would work if we wanted to send arrays over in binary format should #209 ever happen, though. |
My reason is that this PR supports array types. And from my logic, Scanner and Valuer interface always go hand-in-hand and have 1-to-1 map. In other word, if I can bind
Did not know that!? Is is because of performance - 2 roundtrips (which is from your comment in #49). It is not a problem in all of my projects so far. The way we have been doing it, is to prepare all statements at init time, and only call *stmt.Exec/Query/QueryRow at runtime. I think this approach is recommended for security (no/less injection), integrity (panic at init time if there are typos or entity not exists) and performance (no parsing require at runtime). |
Talking of workaround of db.Exec/Query/QueryRow, I think https://github.com/jmoiron/sqlx or some higher wrapper of Go's sql is the only way, because of this line http://golang.org/src/pkg/database/sql/sql.go?s=23949:23985#L884 |
https://gist.github.com/johto/2914cd7309dedc5fb0d8 seems to be working fine; am I missing something? |
I think you mean |
Yes; it's a proof-of-concept.
[]interface{} is horrible for "generic use". interface{} might work; I'd have to see how bad of an effect all of the reflection magic would have on performance. Or there could be specific types for the common types (Int, Time, etc.) and one reflection-based "generic" array.
Maybe. But it works with Query(), which is the point I'm trying to make. If we can make passing arrays directly work for prepared statements, fine. But I have no personal interest in that kind of functionality, and I'm sure I'm not the only one.
Scanning is still a separate feature in my mind. We need to keep the discussions separate, and find the best solutions to both problems. |
Perhaps it's not necessary for you to go and rip this patch into two pieces right now, but both interfaces need to be reviewed separately.
No, prepared statements are actually better in that area in pq, since they only need to do a single roundtrip for execution. But they're a nightmare to deal with when you have live schema changes going on under the app since the server can't invalidate some caches automatically in a safe manner, so you need to do it yourself. I doubt any Go apps actually do this, so they'll just break until they're restarted.
You don't need prepared statements for that, just parameterization. At least in pq, db.Query() is just as safe against injection as stmt.Query().
Not necessarily a feature for all apps..
This can often be true, though. |
Sorry I was a bit unclear on this; I mean it works with db.Query(), i.e. without prepared statements. Note that I'm not suggesting this as the primary interface right now, but as a workaround for the lack of direct value-passing support for anything other than prepared statements. But that might change once I dive deeper into this patch (which I really have not done at all). |
Thanks for the insight, then I think from this I will make a separate PR, scanning (as we are still looking for good-enough workaround for valuing) |
t.Errorf("Expected array[1] to be '%s', got '%s'", expected, v[1]) | ||
} | ||
|
||
if expected := ""; v[2] != expected { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick question... Is this desired? And does it work as expected if you use []sql.NullString
instead of []string
? Maybe add a test using the sql.NullString
type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not being able to distinguish between an empty string and a NULL in an array element is not going to fly. Trying to scan an array with NULL elements into a []string ought to return an error.
d268475
to
3e3efe5
Compare
#49
This PR has support for:
Known limitation: slice type cannot be converted if used directly by db.Exec/Query/QueryRow