Back to Blog

Why Your AI's Boolean Filter Fails Across Databases

WHERE is_active = true works in Postgres and throws a syntax error in SQL Server, where the same column is really a BIT and needs = 1. MySQL's BOOLEAN is secretly a TINYINT too. Why 'true' and 'false' aren't universal SQL, and what to ask for instead.

WHERE is_active = true runs fine against Postgres. Point the same AI client at a SQL Server database with an otherwise-identical schema, and the same filter throws a syntax or conversion error. Nothing about the question changed — the database underneath did, and that's enough.

There's no such thing as "the SQL boolean type"

This is one of the more surprising gaps in SQL standardization: every major database represents true/false differently, and only one of the three common ones actually has a dedicated boolean type at all.

  • PostgreSQL — a genuine BOOLEAN type, with true, false, and NULL (representing "unknown") as real values. WHERE is_active = true (or just WHERE is_active) works exactly as written.
  • MySQLBOOLEAN exists as a keyword, but it's literally an alias for TINYINT(1) — a one-byte integer. true and false are accepted as convenient stand-ins for 1 and 0, but the column is a number underneath, and comparisons, arithmetic, or type-strict tooling can treat it as one.
  • SQL Server — no boolean type at all. The closest equivalent is BIT, storing 0, 1, or NULL. Depending on the SQL Server version and compatibility level, true/false as literals may not be accepted the way they are in Postgres — the safe, universally-correct literals are 1 and 0.

So the exact same intent — "is this account active" — needs = true, = 1 (working via the TINYINT alias), or = 1 (as the only real option) depending purely on which of the three you're connected to.

Why this trips up an AI more than a human developer might expect

A developer who's worked primarily in one database tends to build a strong, mostly-correct instinct for that database's conventions and reach for it automatically — which is exactly the failure mode here too, just via training data instead of personal experience. A model that's seen far more Postgres examples than SQL Server ones in training data will lean toward true/false by default, and that default is simply wrong the moment the connection is actually SQL Server.

This is also why the fix isn't "teach the AI the universal boolean syntax" — there isn't one. The fix is making sure the model checks the actual column type for this connection before assuming, the same discipline that already fixes wrong column namesdescribe_table reveals the real type (boolean, tinyint, bit), which tells you which literal is safe to use.

How this fails — loudly, which is actually the good news

Unlike case-sensitivity or NULL filtering bugs, which silently return fewer rows with no error at all, a boolean type mismatch on SQL Server tends to fail with an explicit syntax or conversion error. That's a meaningfully better failure mode — you get told something is wrong immediately, rather than a quietly-too-low count you might not notice for weeks. The fix is usually as simple as swapping true/false for 1/0 once you know that's what's needed.

The prompt that heads this off

Before filtering on a boolean-looking column, check describe_table for
its actual type. Use true/false for a real BOOLEAN column (Postgres).
Use 1/0 for BIT (SQL Server) or TINYINT-backed BOOLEAN (MySQL) — don't
assume true/false works just because it did on a different database.

The short version

"Boolean" isn't one thing in SQL — it's a real type in Postgres, a number wearing a boolean-shaped costume in MySQL, and a plain number with no costume at all in SQL Server. The filter that "should obviously work" depends on which of the three is actually listening, and checking the real column type before writing the comparison is the only version of this that generalizes.


Read-only MCP gateway across Postgres, MySQL, and SQL Server: mcpserver.design.

Related reading: