Navigation Menu

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

why are select, order by, and group by $ escaped #35

Closed
dvic opened this issue Oct 22, 2019 · 6 comments
Closed

why are select, order by, and group by $ escaped #35

dvic opened this issue Oct 22, 2019 · 6 comments
Labels

Comments

@dvic
Copy link

dvic commented Oct 22, 2019

Is there any particular reason for this? Is there a workaround to use sub-expressions with positional arguments ($1, $2, etc. obtained using .Var()) in these positions?

@huandu
Copy link
Owner

huandu commented Oct 23, 2019

This package uses $0 .. $n to represent placeholders. If the $ is not escaped in Select/OrderBy/etc, there will be some unexpected behavior when building SQL.

Why do you need to use $1/$2 explicitly? Please let me know your scenario. I can help you.

@dvic
Copy link
Author

dvic commented Oct 23, 2019

I lost an hour or so on this issue because .Build() was missing arguments supplied in sb.Var (I used sub-expressions that used positional arguments in the select and order by). This is not what you expect, you expect when you call .Var() on a builder that the variable is always returned in .Build() not matter what, right?

@huandu
Copy link
Owner

huandu commented Oct 23, 2019

Can you please show me some code? I still don't get your point.

@dvic
Copy link
Author

dvic commented Oct 23, 2019

So for example, I cannot create these kind of queries:

	sqlbuilder.DefaultFlavor = sqlbuilder.PostgreSQL
	sb := sqlbuilder.NewSelectBuilder()

	sb.Select("id", fmt.Sprintf("someFunc(some_col, %s)", sb.Var("bar")))
	sb.From("user")
	sb.Where("status = " + sb.Var("foo"))

	sql, args := sb.Build()
	fmt.Println(sql)
	fmt.Println(args)

The output is:

SELECT id, someFunc(some_col, $0) FROM user WHERE status = $1
[foo]

As you can see, bar is missing from the arguments and $0 is present in the query, which makes this query invalid in Postgres (positional arguments start at $1).

@dvic
Copy link
Author

dvic commented Oct 23, 2019

Or a more realistic example, where I want to find users with 'foo' in their name but sort the users whose name starts with 'foo' first:

	sqlbuilder.DefaultFlavor = sqlbuilder.PostgreSQL
	sb := sqlbuilder.NewSelectBuilder()

	foo := sb.Var("foo")
	sb.Select("id")
	sb.From("user")
	sb.Where("name ~* " + foo)
	sb.OrderBy(fmt.Sprintf("name ~* '^' || %s DESC", foo)) // DESC here because BOOL is sorted FALSE, TRUE

	sql, args := sb.Build()
	fmt.Println(sql)
	fmt.Println(args)

Prints

SELECT id FROM user WHERE name ~* $1 ORDER BY name ~* '^' || $0 DESC
[foo]

I understand now why this happens, but it's not desired I think, not sure how to fix this without introducing breaking changes.

@huandu
Copy link
Owner

huandu commented Oct 24, 2019

OK. I get it. I wasn't aware of your use cases. I can fix it soon.

@huandu huandu added bug and removed question labels Oct 24, 2019
@huandu huandu closed this as completed in aa3d965 Oct 25, 2019
huandu added a commit that referenced this issue Oct 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants