sequelize / sequelize/sequelize

Find query missing FROM clause when using `include: separate: false`

Open
#11,146 5 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dialect: postgres type: bug
Dominant language
TypeScript
Stars
30.4k
Forks
4.3k
Avg merge
1d 6h
Merged PRs (30d)
68

Description

What are you doing?

// Creation
this.Task = this.sequelize.define('Task', { title: Sequelize.STRING });
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING });
this.Worker.hasMany(this.Task, { as: 'ToDos' });
return this.Worker.sync({ force: true }).then(() => {
  return this.Task.sync({ force: true }).then(() => {
    return this.Worker.create({ name: 'worker' }).then(worker => {
      return this.Task.create({ title: 'homework' }).then(task => {
        this.worker = worker;
        this.task = task;
        return this.worker.setToDos([this.task]);
      });
    });
  });
});
});

return this.Worker.findAll({
  order: [
    ['id', 'DESC']
  ],
  where: {
    '$ToDos.title$': "homework",
  },
  include: [
    { model: this.Task, as: 'ToDos', separate: false },
    { model: this.Task, as: 'ToDos', separate: true },
  ]
}).then(workers => {
  expect(workers).to.exist;
  expect(workers[0].name).to.equal('worker');
  expect(workers[0].ToDos).to.exist;
  expect(workers[0].ToDos[0].title).to.equal('homework');
});

To Reproduce

I created a test case to reproduce the error. To run the test:

$ git checkout 5e8dcaa0265b361a27affdeb61f6a6a63a1bf643

Open file: test > integration > model > findAll.test.js. Go to describe("hasMany with alias") section, and paste this following test case:

        it.only('returns the associated task via worker.task', function() {
          return this.Worker.findAll({
            order: [
              ['id', 'DESC']
            ],
            where: {
              '$ToDos.title$': "homework",
            },
            include: [
              { model: this.Task, as: 'ToDos', separate: false },
              { model: this.Task, as: 'ToDos', separate: true },
            ]
          }).then(workers => {
            expect(workers).to.exist;
            expect(workers[0].ToDos).to.exist;
            expect(workers[0].ToDos[0].title).to.equal('homework');
          });
        });

Run tests

$ docker-compose up -d postgres-95
$ DEBUG=sequelize:sql* DIALECT=postgres npm run test-docker-integration

What do you expect to happen?

Generated SQL code that includes a FROM clause for the "Task" (well, the "ToDos" table here since it's an association) table so that my Worker findAll() query can run successfully.

I expect generated SQL code such as: SELECT "Worker"."id", "Worker"."name", "Worker"."createdAt", "Worker"."updatedAt" FROM "Workers", "ToDos"."title" FROM "ToDos" AS "Worker" WHERE "ToDos"."title" = 'homework' ORDER BY "Worker"."id" DESC; (not sure if this SQL compiles, but the key here is FROM "ToDos")

What is actually happening?

SequelizeDatabaseError: missing FROM-clause entry for table "ToDos" with generated SQL code: SELECT "Worker"."id", "Worker"."name", "Worker"."createdAt", "Worker"."updatedAt" FROM "Workers" AS "Worker" WHERE "ToDos"."title" = 'homework' ORDER BY "Worker"."id" DESC;

Notice the SQL code includes the correct WHERE statement, but does not include a FROM statement.

Note: When running this code with sequelize versions 4.43.0, 4.44.0, the SQL code is generated successfully. When running with sequelize versions: 5.1.0, 5.9.2, 5.8.12, the FROM clause does not generated for the include.

Environment

Dialect:

  • mysql
  • postgres
  • sqlite
  • mssql
  • any
    Dialect library version: ??? What is this?
    Database version: sushantdhiman/postgres:9.5
    Sequelize version: 5.1.0, 5.9.2, 5.8.12
    Node Version: 10 LTS
    OS: Linux, Macos (running in Docker)
    Tested with latest release:
  • No
  • Yes, specify that version: 5.9.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with test/integration/model/findAll.test.js in the describe("hasMany with alias") section, using commit 5e8dcaa0265b361a27affdeb61f6a6a63a1bf643 and the PostgreSQL integration command provided. Trace the generated SQL for the two ToDos includes and confirm the query includes the required FROM entry and the test passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js, postgresql
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.