Skip to content
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

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

Open
PavelSafronov opened this issue Jun 26, 2023 · 7 comments

Comments

@PavelSafronov
Copy link

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?

@taylorchu
Copy link
Contributor

taylorchu commented Jun 26, 2023

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

@PavelSafronov
Copy link
Author

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)

@taylorchu
Copy link
Contributor

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.

@PavelSafronov
Copy link
Author

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.

@taylorchu
Copy link
Contributor

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.

@PavelSafronov
Copy link
Author

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

@taylorchu
Copy link
Contributor

taylorchu commented Jun 27, 2023

dbr.Expr generates non-quoted texts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants