SQL Identifier Portability Checker
Paste a proposed table or column name — or a list of them, one per line — and see exactly which of PostgreSQL, MySQL, SQL Server and SQLite would reject it, silently rename it, or otherwise treat it inconsistently, and why.
Processed locally in your browser. Your file is never uploaded.
How to use this calculator
- Paste one identifier per line — a table name, column name, or a batch of several. Nothing leaves your browser.
- Select "Check identifiers".
- Review each flagged name: which specific engines are affected and which aren't, and why.
- Use the suggested rewrite where one is offered — reserved-word collisions and quoting-style choices are left for you to decide, since both require a judgment call this tool shouldn't make unilaterally.
Assumptions
- Input is one identifier per line — a bare name, or a name already wrapped in one engine's quote style (double quotes, backticks or square brackets). This is not a SQL parser: a full `CREATE TABLE` statement or multi-column definition isn't parsed, only the identifier shape itself.
- The four target engines are PostgreSQL, MySQL, SQL Server (T-SQL) and SQLite — the four most commonly hit in real cross-database portability work.
- The reserved-word table is a curated, well-documented common-collision subset, not an exhaustive list for any engine — see Limitations.
Methodology
Each identifier is checked against six specific, documented portability pitfalls: reserved-word collision (checked per engine, since a word can be reserved in one engine and not another), case-folding divergence (PostgreSQL lowercases unquoted identifiers, MySQL's case-sensitivity depends on OS/settings, SQL Server is case-insensitive-but-preserving, SQLite is case-sensitive), quoting-syntax differences (double quotes vs backticks vs square brackets), identifier length limits (63 bytes for PostgreSQL with silent truncation, 64 characters for MySQL, 128 for SQL Server, no practical limit for SQLite), invalid unquoted characters, and the leading-underscore naming convention. A rewrite is offered only for the two mechanically unambiguous cases — lowercasing for case-folding, underscore-substitution for invalid characters — never for a reserved-word rename or a quote-style choice.
Worked example
A word reserved in some engines but not all
Inputs: limit
Result: "limit" is a reserved word in PostgreSQL, MySQL and SQLite, but SQL Server has no LIMIT clause at all (it uses TOP / OFFSET-FETCH instead), so "limit" isn't reserved there. Flagged as an error naming exactly which three engines are affected.
A mixed-case identifier
Inputs: CustomerOrder
Result: PostgreSQL would silently fold this to "customerorder" if left unquoted, while MySQL, SQL Server and SQLite each have their own inconsistent case-handling rules. Flagged as a warning; rewritten to "customerorder" as the safe portable convention.
Spaces and a hyphen
Inputs: customer order-id
Result: Not a valid bare identifier in any of the four engines — each would need it quoted with a different quote character. Flagged as an error; rewritten to "customer_order_id" using underscores, the universally safe convention.
Practical guidance
- Stick to lowercase, underscore-separated names (`snake_case`) for any table or column that might ever be queried from more than one database engine — it sidesteps case-folding divergence entirely.
- Avoid reserved words outright rather than relying on quoting — quoting works, but it means every single query against that table must remember to quote it, in that engine's specific quote style, forever.
- Keep identifiers well under 63 characters if PostgreSQL is a possible target — its silent truncation at that length is a genuinely dangerous failure mode, not just an inconvenience.
Common mistakes
- Assuming a name is safe because it isn't reserved in the database you're testing against right now — several common words (order, user, limit, key, index) are reserved in some engines and not others, so testing against only one engine hides the problem.
- Treating quoting as a universal fix — it works, but the quote character itself is engine-specific, so a quoted identifier copied verbatim between engines still won't parse.
- Not noticing PostgreSQL's silent truncation at 63 bytes — unlike a rejected identifier, a truncated one still works, right up until two long names collide.
FAQs
Why is "limit" flagged for three engines but not SQL Server?
SQL Server doesn't have a LIMIT clause — it uses TOP or OFFSET/FETCH instead — so LIMIT was never reserved as a keyword there. It's reserved in PostgreSQL, MySQL and SQLite because all three use LIMIT in their query syntax.
Will quoting a reserved word always fix it?
In practice, yes, in all four engines here — but the quote character differs per engine (double quotes for PostgreSQL/SQLite, backticks for MySQL, square brackets for SQL Server), so a quoted name copied as-is from one engine's SQL won't parse in another's. This tool lists each engine's equivalent quoted form rather than picking one for you.
Is a leading underscore actually a problem?
No — it's flagged only as a minor, informational note. It isn't invalid in any of the four engines; it's worth knowing about only because PostgreSQL's own internal catalog objects and some ORMs use leading-underscore names by convention.