gocraft/dbr

`InterpolateForDialect("SHOW CREATE TABLE ?;"...)` produces invalid MySQL statement

PavelSafronov opened this issue · 7 comments

Repro code:

package main

import (
	"fmt"
	"github.com/gocraft/dbr/v2"
	"github.com/gocraft/dbr/v2/dialect"
)

func main() {
	q, _ := dbr.InterpolateForDialect("SHOW CREATE TABLE ?;", []interface{}{"foo"}, dialect.MySQL)
	fmt.Println(q)
}

Sandbox link showing this execution: https://go.dev/play/p/QGDpepYMCfM

The above code produces the following MySQL statement: SHOW CREATE TABLE 'foo';.
This MySQL statement is not valid, because MySQL is not expecting ' (quotes) around the table name. MySQL docs in question.

Is there a way to invoke InterpolateForDialect in such a way that we can get the injection protection, but avoid quoting a particular parameter? Should we be using a different method entirely?

you should use dbr.I (identifier) instead of string

Can you give an example of that?

I tried this, but in the generated query, foo was still quoted.

dbr.InterpolateForDialect("SHOW CREATE TABLE ?;", []interface{}{dbr.I("foo")}, dialect.MySQL)

Is there a way to invoke InterpolateForDialect in such a way that we can get the injection protection, but avoid quoting a particular parameter? Should we be using a different method entirely?

package main

import (
	"fmt"

	"github.com/gocraft/dbr/dialect"
	"github.com/gocraft/dbr/v2"
)

func main() {
	fmt.Println(dbr.InterpolateForDialect("SHOW CREATE TABLE ?;", []interface{}{dbr.I("foo")}, dialect.MySQL))
}

SHOW CREATE TABLE foo

dbr.I will now quote with tick.

Ah, thank you so much, I didn't notice that using dbr.I produces ticks instead of single quotes. The returned query is now perfectly valid.

Can this approach be documented somewhere? This information is necessary for using the function, but isn't very discoverable.

yes.

func ExampleI() {
        // I, identifier, can be used to quote.
        I("suggestions.id").As("id") // `suggestions`.`id`
}

it is there. this issue is helpful for future :)

dbr.I is just a proxy to quoteident, which is used in almost every places.

Thanks for that pointer.

I'm looking in the examples, but not finding this other case: is there a way to invoke InterpolateForDialect so the values aren't quoted/ticked at all? (I can also make a new issue to ask this question, if you'd prefer that.)

dbr.Expr generates non-quoted texts