Skip to content

docs: fix query examples that throw or show the wrong SQL - #855

Open
yxshee wants to merge 1 commit into
sequelize:mainfrom
yxshee:fix/example-output-mismatches
Open

yxshee wants to merge 1 commit into
sequelize:mainfrom
yxshee:fix/example-output-mismatches

Conversation

@yxshee

@yxshee yxshee commented Oct 26, 2026

Copy link
Copy Markdown

Description of Changes

I ran the code examples on these pages against @sequelize/core built from the current main of sequelize/sequelize (and 7.0.0-alpha.48 from npm, which gives the same results). For SQL I used the query generator of the postgres and mysql dialects, and real queries on SQLite in memory. These examples either throw or show SQL that Sequelize does not generate. There is no issue for this; the list below describes each problem.

querying/select-in-depth.md

  • The option is subQuery, not subquery. With subquery: false the option is ignored, the subquery stays, and the query fails with no such column: projects.name. With subQuery: false it runs as a plain JOIN.
  • The subquery passed to Op.in had no parentheses and no FROM clause. Sequelize inserts an Op.in literal as is, so this produced "id" IN SELECT ..., which is a syntax error. I added the parentheses and the FROM "projects". On SQLite it now returns the users who have "Project 1".
  • findOne returns one instance, so JSON.stringify(author[0]) printed undefined. It is now JSON.stringify(author).

querying/sub-queries.md

  • The decorators were imported from @sequelize/decorators-legacy, which does not exist (npm returns 404). They are exported from @sequelize/core/decorators-legacy, like on the other pages.
  • NonAttribute was used but not imported.
  • storage: ':memory:' without the pool settings throws "SQLite is configured to use a temporary database, but the pool is configured to close idle connections". I added the same pool option that the SQLite page recommends.
  • Both Op.in literals got the same missing parentheses fix as above. The first example now returns the expected post. The second one, which interpolates ${type}, still fails on main because the interpolated value gets validated against the id attribute's INTEGER type ('Laugh' is not a valid integer). That is a problem in core, not in the docs, so I left the rest of that example as it was.

querying/raw-queries.mdx

  • sql.uuidV4 and sql.random are values, not functions. ${sql.uuidV4()} and ${sql.random()} throw TypeError: ... is not a function. With ${sql.uuidV4} postgres generates gen_random_uuid(), and with ${sql.random} it generates RANDOM(), which matches the table on the page.
  • sql.join(values, sql, ) does not add parentheses, so IN ${...} generated status IN 'active', 'pending'. I added the parentheses, the same way the example just above does it.
  • The sql.identifier(Model) example imported User from @sequelize/core (no such export) and then used Model without importing it. It now imports Model.

querying/json.mdx

  • 'gameData.passwords[0]': 0451 is a legacy octal literal. In TypeScript and ES modules it is a syntax error (TS1121: Octal literals are not allowed). In sloppy-mode JS it is 297, so the query compared against '297'. I changed it to the string '0451', which generates = '"0451"'.
  • In the nested extraction example, age: 18 is stringified to JSON like any other value, so the comparison is = '18', not = 18. Postgres has no jsonb = integer operator.
  • In the mysql line of the or(SQL_NULL, JSON_NULL) example, the JSON null check was shown as = '"null"'. That is the JSON string "null", which the table further down says does not match. Sequelize compares against 'null'.

querying/operators.mdx

  • In the first custom LIKE example the generated SQL showed the escaped JS string (10\\%, '\\') instead of the SQL Sequelize produces for postgres (10\%, '\'). The second example at the bottom of the page already shows the right form.

other-topics/scopes.md (v7 and v6)

  • sequelize and modelName were nested inside scopes, so Model.init throws ("Model.init expects a Sequelize instance" in v7, "No Sequelize instance passed" in v6.37.8). I moved them up one level. With that change Model.init succeeds. I tested it with the deleted, random and accessLevel scopes (I left out activeUsers because it needs a User model).

How I checked it

  • I built @sequelize/core, @sequelize/postgres, @sequelize/mysql and @sequelize/sqlite3 from sequelize/sequelize main (b7f5857). Then I compared the generated SQL from queryGenerator.whereQuery and queryGenerator.escape against each corrected snippet.
  • I ran the select-in-depth and sub-queries examples on SQLite in memory with seeded rows, before and after the change.
  • I type-checked the sub-queries setup and the sql.identifier import with tsc 5.9. The old versions fail with TS2307, TS2304 and TS2614. The new versions pass.
  • I ran the v6 scopes example with sequelize@6.37.8.
  • prettier --check passes on the changed files. The lint-staged hook also ran on commit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQDmA3mwGfL83pbg9WQ6ey
@yxshee
yxshee requested a review from a team as a code owner October 26, 2026 12:14
@yxshee
yxshee requested review from ephys and sdepold October 26, 2026 12:14

This branch has not been deployed

No deployments
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.

1 participant