Skip to content

BREAKING CHANGE: split aggregate arguments by space rather than \s+#16145

Open
vkarpov15 wants to merge 2 commits into10.0from
vkarpov15/gh-16126
Open

BREAKING CHANGE: split aggregate arguments by space rather than \s+#16145
vkarpov15 wants to merge 2 commits into10.0from
vkarpov15/gh-16126

Conversation

@vkarpov15
Copy link
Copy Markdown
Collaborator

Fix #16126

Summary

Splitting by \s+ is considerably slower than just plain ' ' so we should switch to that.

Examples

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes Aggregate.prototype.project() and Aggregate.prototype.sort() string argument parsing by replacing regex-based splitting (/\s+/) with plain space splitting (' '), consistent with the projection parsing optimization discussed in #16126.

Changes:

  • Update project() to split string arguments using ' ' with a no-space fast path.
  • Update sort() to split string arguments using ' ' with a no-space fast path.
  • Refactor object-argument iteration in project() to use a for...of loop.

Comment on lines +261 to +267
} else {
const include = arg[0] === '-' ? 0 : 1;
if (include === 0) {
field = field.substring(1);
arg = arg.substring(1);
}
fields[field] = include;
});
fields[arg] = include;
}
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new no-space fast path treats an empty string ('') as a field name and produces { $project: { '': 1 } }, whereas the previous split(/\s+/) logic would ignore empty tokens and result in an empty projection object. This is a behavior change that will generate invalid pipeline stages for project('') (and similarly for strings that become empty after trimming). Consider normalizing to the same tokenization approach as parseProjection() (wrap in an array when there are no spaces, then skip falsy tokens) or explicitly handling arg === '' before computing include.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this should likely have a !arg check as the other branch.

Copy link
Copy Markdown
Collaborator

@AbdelrahmanHafez AbdelrahmanHafez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicky suggestion:
Add a test that asserts other types of whitespace aren't used to split.

Copy link
Copy Markdown
Collaborator

@hasezoey hasezoey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good to me, but Copilout points out that empty strings are treated as a field, which likely should not be the case.
Also consider adding "other whitespace character" tests as Hafez pointed out.

Comment on lines +261 to +267
} else {
const include = arg[0] === '-' ? 0 : 1;
if (include === 0) {
field = field.substring(1);
arg = arg.substring(1);
}
fields[field] = include;
});
fields[arg] = include;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this should likely have a !arg check as the other branch.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@vkarpov15 vkarpov15 modified the milestones: 9.3.2, 10.0 Mar 23, 2026
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

Successfully merging this pull request may close these issues.

4 participants