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

fix: select everything when forming subspell #382

Merged
merged 1 commit into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/querying.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,36 @@ Post.include('comments', 'author')
Post.find().with('comments').with('author')
```

Please be noted that the chaining order of `.with()` matters, queries like below are not equivalent:

```js
Post.findOne().with('comments')
// NOT EQUALS TO
Post.find().with('comments').first
```

By type definitions, both queries will return a Post instance or null depending on the record can be found or not. But the generated SQLs are quite different:

```sql
SELECT * FROM (SELECT * FROM posts LIMIT 1) AS posts LEFT JOIN comments ON comments.post_id = posts.id
-- NOT EQUALS TO
SELECT * FROM posts AS posts LEFT JOIN comments ON comments.post_id = posts.id LIMIT 1
```

The major difference is the place of `LIMIT`, the former query will fetch the first post and all of its associated comments, the latter query however, will only return the first post and its first comment.

We can keep on chaining the query methods if comments need to be limited as well:

```js
Post.findOne().with('comments').limit(10)
```

which is equivalent of SQL below:

```sql
SELECT * FROM (SELECT * FROM posts LIMIT 1) AS posts LEFT JOIN comments ON comments.post_id = posts.id LIMIT 10
```

### Arbitrary Joins

If a join is needed but not predefined in `Model.describe()`, it can still be accomplished with `.join()`:
Expand Down
30 changes: 30 additions & 0 deletions docs/zh/querying.md
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,36 @@ Post.include('comments', 'author')
Post.find().with('comments').with('author')
```

注意,链式调用 `.with()` 产生的作用会跟调用顺序有关系,下面两个写法是不等价的:

```js
Post.findOne().with('comments')
// 不等同于
Post.find().with('comments').first
```

虽然从接口定义来看,两者都会返回 Post 实例或者 null,但是两者所执行的 SQL 会有差别:

```sql
SELECT * FROM (SELECT * FROM posts LIMIT 1) AS posts LEFT JOIN comments ON comments.post_id = posts.id
-- 不等同于
SELECT * FROM posts AS posts LEFT JOIN comments ON comments.post_id = posts.id LIMIT 1
```

可以看到区别在于 LIMIT 所在的位置,前者会返回第一条 Post 及其所有的 Comment,后者则只会返回第一条 Post 及其第一条 Comment。

使用第一种查询时,如果需要限制返回的评论数量,可以直接写:

```js
Post.findOne().with('comments').limit(10)
```

等价于下面的 SQL:

```sql
SELECT * FROM (SELECT * FROM posts LIMIT 1) AS posts LEFT JOIN comments ON comments.post_id = posts.id LIMIT 10
```
Copy link
Owner Author

Choose a reason for hiding this comment

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

加了一点文档说明,这个改动价值蛮大的


### 任意 JOIN

如果需要 JOIN 未在 `Model.describe()` 预先定义的关联关系,可以使用 `.join()` 方法:
Expand Down
5 changes: 2 additions & 3 deletions src/spell.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,7 @@ class Spell {

#emptySpell() {
Object.assign(this, {
columns: [],
whereConditions: this.Model.shardingKey ? this.whereConditions : [],
// whereConditions: [],
whereConditions: [],
groups: [],
orders: [],
havingConditions: [],
Expand Down Expand Up @@ -808,6 +806,7 @@ class Spell {
$with(...qualifiers) {
if (this.rowCount > 0 || this.skip > 0) {
const spell = this.dup;
spell.columns = [];
this.#emptySpell();
this.table = { type: 'subquery', value: spell };
}
Expand Down
8 changes: 8 additions & 0 deletions test/integration/suite/associations.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,5 +324,13 @@ describe('=> Associations order / offset / limit', function() {
assert.equal(posts[0].title, 'New Post');
assert.equal(posts[0].comments.length, 2);
});

it('on subquery with select', async function() {
await assert.doesNotReject(async function() {
const post = await Post.first.select('title').with('comments');
assert.ok(post);
assert.ok(Array.isArray(post.comments));
});
});
});
});
11 changes: 0 additions & 11 deletions test/integration/suite/sharding.test.ts
Copy link
Owner Author

Choose a reason for hiding this comment

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

这个看上去是 false alarm,先回滚掉了

This file was deleted.