Interpolation of []byte arguments fails
Call
db.Exec(`INSERT INTO table (binary_column) VALUES (?)`, []byte{42})
Expected
"\x2a" is inserted into the database
Actual
Query parsing fails at ... ([42]) because driver/stmt.go expects fmt.Sprintf("%v", args[i]) to produce parseable SQL.
Suggested fixes
- One option: interpolate []byte as "$$" + string(byteArray) + "$$" and hope byteArray doesn't contain any dollar signs
- Another option: teach engine/parser/lexer.go to lex interpolated byte arrays, i.e.
[num num num ...]where each num is 0 ≤ num ≤ 255 - Third option (my favorite): come up with an interpolation syntax that's more similar to standard SQL (e.g.
0x48656c6c6ffor "Hello") and have driver/stmt.go format []byte as that
Hi,
Your third option is indeed the way to go I think, since the parser must handle byte array format when written directly in the query (or via command line).
So having a specific formatting in stmt parameter resolver would fix this issue, although I think the right way to do this would be to leave parameter placeholder in the query and fix parser to handle them directly. Right now stmt format value in string to be then parsed by handler, it's a really awful behavior.
Anyway thanks for the issue! Feel free to create a PR, I'll otherwise try to fix this when I get some time
We ultimately decided to use github.com/mattn/go-sqlite3 for our purposes, as it supports in-memory databases and supports real SQL syntax (e.g. UPDATE foo SET a = a + 1 WHERE b = 42). But I'd be interested in helping to improve ramsql on my own time (hence the switch to my personal GH account).
I've got some ideas on how to overhaul the lexer and parser, to support much more advanced SQL syntax. Would you be interested in contributions along those lines?
Sure, sqlite3 is good, thanks for the update
I'm definitely interested by any contribution, especially about lexer/parser. It's a really archaic and naive piece that should be redesigned. There is even a case to be made about code generation for this, especially in Go. Anyway, fire away :)
Digging up this old issue. I have a use case where I need to use postgres to store bytes and I'd like to unit test it using this in memory solution.
I've gotten by using github.com/mattn/go-sqlite3 until I needed to use LastInsertedId() (which postgres doesn't support, but sqlite does).
Anyway, consider my comment a +1 to this feature request/bugfix
fixed by https://github.com/proullon/ramsql/commit/dfa934570278763bb69f52a3e9b935df6cb84577