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

Subqueries in insert statements #627

Closed
whitelynx opened this Issue Jan 15, 2015 · 2 comments

Comments

Projects
None yet
2 participants
@whitelynx
Contributor

whitelynx commented Jan 15, 2015

Using a subquery inside .insert() without wrapping it in a function yields an incorrect query.

Is there a reason for the requirement of wrapping the subquery in a function? I can't think of any use case where a user passing a subquery QueryBuilder instance to one of the functions would not want it wrapped with parenthesis.

As far as implementation, we could change Formatter#parameter() to check for subqueries by checking if value instanceof QueryBuilder like Formatter#checkRaw() does.


Test cases

Case 1: A literal value

This query works as expected:

db('geom_text').insert({description: 'a point!', geom: 'POINT(-71.064544 42.28787)'}).toString();

...this results in:

insert into "geom_text" ("description", "geom") values ('a point!', 'POINT(-71.064544 42.28787)')

Case 2: A direct subquery

This one, however, fails:

var subquery = db().select(db.raw('?', ['POINT(-71.064544 42.28787)']));
db('geom_text').insert({description: 'a point!', geom: subquery}).toString();

...resulting in:

insert into "geom_text" ("description", "geom") values ('a point!', select 'POINT(-71.064544 42.28787)')

Case 3: A subquery returned by a function

This query, works as expected again:

db('geom_text').insert({description: 'a point!', geom: function()
{
    return this.select(db.raw('?', ['POINT(-71.064544 42.28787)']));
}}).toString();

...resulting in:

insert into "geom_text" ("description", "geom") values ('a point!', (select 'POINT(-71.064544 42.28787)'))
@bendrucker

This comment has been minimized.

Collaborator

bendrucker commented Jan 15, 2015

So this is more an omission than anything. Knex is calling toString implicitly and that's why the value isn't wrapped. Your solution sounds fine to me.

@whitelynx

This comment has been minimized.

Contributor

whitelynx commented Jan 15, 2015

Actually, looking at it again, Formatter#parameter() calls Formatter#checkRaw(), which does the check for a QueryBuilder instance... the problem seems to be simply that the parameter isn't passed through to Formatter#outputQuery()'s alwaysWrapped flag, which it probably should be.

I'll get that in a PR.

whitelynx added a commit to whitelynx/knex that referenced this issue Jan 15, 2015

whitelynx added a commit to whitelynx/knex that referenced this issue Jan 15, 2015

gjvargas pushed a commit to gjvargas/knex that referenced this issue Jan 22, 2015

gjvargas pushed a commit to gjvargas/knex that referenced this issue Jan 22, 2015

tgriesser added a commit that referenced this issue Feb 25, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment