ramsql icon indicating copy to clipboard operation
ramsql copied to clipboard

Interpolation of []byte arguments fails

Open dkfitbit opened this issue 7 years ago • 4 comments

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. 0x48656c6c6f for "Hello") and have driver/stmt.go format []byte as that

dkfitbit avatar Feb 15 '18 19:02 dkfitbit

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

proullon avatar Feb 15 '18 20:02 proullon

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?

chronos-tachyon avatar Feb 23 '18 04:02 chronos-tachyon

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 :)

proullon avatar Feb 23 '18 09:02 proullon

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

tatemz avatar Jan 06 '21 04:01 tatemz

fixed by https://github.com/proullon/ramsql/commit/dfa934570278763bb69f52a3e9b935df6cb84577

proullon avatar Feb 22 '23 00:02 proullon