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
fix: minified aliases are now properly referenced in subqueries (v6) #14852
Conversation
Do we need the linting fixes? They're not in files related to this PR and I would prefer to limit the changes that we do in v6 |
Well. I just ran lint --fix and this was the result. I wonder how it could have worked before since I expected the linter to fail if there are things to change |
I suppose I can remove the linting commit if we feel strong about it |
This reverts commit efab1ea.
@WikiRik better? |
Linter still passes, so I'm fine with this. Thanks! |
@tomquist Any chance you can test this on your project to make sure it works for your use case? |
@WikiRik Thanks! I tested it on our project. It all works fine if we enforce a subquery using
The error is:
|
@evanrittenhouse could you check this new case out? |
I think the issue I mentioned is an existing issue and nothing introduced by this bugfix. I can also open a new issue for the |
Do I understand the code right, that you want to have a query that aliases Foo.myname as order_0 and then you want to sort by order_0? With this code in place, we are currently generating
|
Ah I see some brackets are missing. So the issue is that this: await Foo.findAll({attributes: {include: [[sequelize.literal(`"Foo".my_name`), "order_0"]]}, order: [["order_0", "DESC"]]}) generates this query: SELECT "id", "my_name" AS "_0", "Foo".my_name AS "_1" FROM "Foos" AS "Foo" ORDER BY "Foo"."order_0" DESC; |
@tomquist what would you expect instead? |
I'd expect this:
|
Excellent. Thanks for the clarification |
Just pushed a change that might fix the issue. It's funny because I just removed a guard that was specifically targeting subQueries and enabled the logic in general. |
@tomquist @WikiRik @evanrittenhouse let's see if this works :) |
interesting. so mssql is additionally adding a sorting in it's query generator on top of the abstract order by fragments. |
@tomquist can you pleas test the new version? I'll figure out the mssql issue meanwhile |
if (!options.order || !options.order.length) { | ||
fragment += ` ORDER BY ${tablePkFragment}`; | ||
} else { | ||
const orderFieldNames = _.map(options.order, order => order[0]); | ||
const primaryKeyFieldAlreadyPresent = _.includes(orderFieldNames, model.primaryKeyField); | ||
const orderFieldNames = (options.order || []).map(order => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a function that is doing this already? Taking a name like thing and returns its string content?
let primaryKey = model.primaryKeyField; | ||
|
||
const tablePkFragment = `${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(primaryKey)}`; | ||
const aliasedAttribute = (options.attributes || []).find(attr => Array.isArray(attr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a copy from the generic query generator. I was about to refactor this function but then wondered if _getAliasForField
should somehow take care of this logic. I'm still not 100% sure what we are even doing here but I supposed, that this piece of code combined with getAliasForField is basically catering for 1) model definition based aliases (using the field property?) and 2) aliases that are introduced during the query calls (e.g. findAll).
Maybe instead of doing this manually, we should have a bit of code inside of _getAliasForField that is checking the options and extracts the call alias from them?
I'm a little bit lost on why MSSQL is having additional logic wrt order but it's probably there for good reasons. Anyway, because of this, it becomes a bit more convoluted and messy. We could clean up MSSQL but I wonder if that should happen in v7 only? |
}); | ||
const primaryKeyFieldAlreadyPresent = orderFieldNames.some( | ||
fieldName => fieldName === (primaryKey.col || primaryKey) | ||
); | ||
|
||
if (!primaryKeyFieldAlreadyPresent) { | ||
fragment += options.order && !isSubQuery ? ', ' : ' ORDER BY '; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit crazy that this is done manually. I was tempted to somehow inject this idea into the incoming order options so that this.getQueryOrders would do the heavy lifting for us
@WikiRik @evanrittenhouse ready for review |
Let's review #14882 first and then get back to this one |
@WikiRik @evanrittenhouse can you review this guy? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's not the prettiest but it seems to work for v6 so we should be good
Thanks Rik! |
🎉 This PR is included in version 6.21.4 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Was this the only change from 6.20.1? Am getting "No context available. ns.run() or ns.bind() must be called first." error when using transactions. |
Sounds like a continuation local storage issue, but we haven't touched that part of the code in recent releases |
This PR seems to be causing an issue for me. See #15422 |
Backport of #14804 to v6 + fix for mssql order duplication