SQL compatibility check
Fabric has several SQL engines, and they don't take the same SQL. The SQL query page checks what you write against the engine you pick, as you type, and lists what that engine doesn't support or may run differently. It is in preview.
The check is static: Fabric Desktop by KratosBI reads the SQL; it doesn't run it, doesn't connect to Fabric and uses no capacity. It never changes your SQL. Each finding says what to change, and you decide.
No findings means no known problem, not proof that the query runs, or gives the same answer, in Fabric. A query that runs on this PC with DuckDB says nothing about how a Fabric Warehouse runs it.
Pick the engine#
The dialect list next to Run is also the engine the SQL is checked against:
| Engine | What the check looks for |
|---|---|
| Spark SQL (Lakehouse) | T-SQL that isn't Spark SQL (TOP, [names], @variables, GO, T-SQL functions), and where running on this PC with DuckDB can differ from Fabric Spark: regular expressions, date patterns, unordered aggregates, decimals, writes that only happen in Fabric |
| Fabric Warehouse (T-SQL) | What Microsoft documents as unsupported in Fabric Data Warehouse: data types in tables, ALTER TABLE limits, keys that must be NOT ENFORCED, triggers, sequences, recursive queries, FOR XML, transaction limits, and differences such as case-sensitive text and whole-number division |
| Fabric SQL analytics endpoint (T-SQL) | As for Warehouse, and that lakehouse tables are read-only through the endpoint: no table DDL, no INSERT, UPDATE, DELETE or MERGE |
| Fabric SQL database (T-SQL) | What the SQL database limitations page lists: EXECUTE AS, BACKUP, change data capture, SQL Agent, Service Broker, in-memory and ledger tables, logins, distributed transactions, column names, cross-database and linked-server names |
| DuckDB (this PC) | T-SQL syntax, and that DuckDB SQL runs only on this PC |
T-SQL is checked and formatted here but never run on this PC.
Findings#
Findings are underlined in the editor, marked in the gutter and listed in the Compatibility panel beside it. Hover an underline, or pick a finding in the panel, to see:
- the severity and rule ID (for example
SYN-001); - what's wrong and why, in the engine's terms;
- what to do instead;
- the target engine, line and column;
- the confidence (high, medium or low) and a Source link to the Microsoft or Apache page the rule comes from.
| Severity | Means |
|---|---|
| Error | Microsoft documents it as unsupported on that engine, or it isn't that engine's SQL. Change it before running it there. |
| Warning | It may run but behave differently than you expect, it's in preview, or it changes or deletes data (DROP, TRUNCATE, DELETE or UPDATE without WHERE). A warning doesn't mean the query is wrong. |
| Information | A documented difference worth knowing, such as snapshot isolation or the UTC clock. |
| Unverified | The check couldn't decide: the statement couldn't be read, a function isn't one it knows, or the documentation doesn't say. Test it in Fabric. |
The panel shows the engine, the rule set's version, the number of statements, the count of each severity and an outcome: Known problems, Review the warnings, Not verified, or No known problems found by static checks. There is no percentage score: a count of rules passed says nothing about whether a query works.
When you run Spark SQL or DuckDB on this PC and the check found differences from Fabric, a note under the results says so. It never stops the run.
Queries over 100,000 characters are checked when you press Check now in the panel, so typing never waits on the engine; scripts over 500,000 characters aren't checked. The panel lists the first 1,000 findings; the counts include all of them.
Export#
Export JSON saves the report to your Downloads folder as <query name> compatibility <engine> <date time>.json. It never replaces a file: a name that's taken gets a number. The file holds the SQL that was checked and its SHA-256 hash, the engine, the rule set version, every finding with its fields, the counts and the outcome (schema: sql-compat-report@1). It holds the SQL, so treat it like the query itself.
What it doesn't do#
- Run the SQL, sign in, call Fabric or use capacity.
- Rewrite your SQL.
- Know your tables' column types, your warehouse's collation or your Fabric runtime version; findings that depend on them are warnings or unverified.
- Check every construct. Statements the engine treats as commands (GRANT, DBCC, SHOW, OPTIMIZE and similar) are checked only by the rules that read their words.
- Put SQL text or findings in the security audit log, or put string literals in findings: a password in the SQL never shows in a message.
Rules#
Rule set 2026.10.1, from Microsoft Learn and the Apache Spark 3.5 reference as they read on 2026-10-17. Each Microsoft page's "last updated" date is kept in sidecar/fabric_desktop/sqlcompat/profiles.py. DDL-007 (ALTER TABLE) is an error except ALTER COLUMN, which is a warning because it is in preview.
| Rule | Finding | Severity | Engines | Confidence | Source |
|---|---|---|---|---|---|
| SYN-001 | LIMIT isn't T-SQL | error | Warehouse, Endpoint, SQL database | high | source |
| SYN-002 | TOP is T-SQL, not the target | error | Spark, DuckDB | high | source |
| SYN-003 | [Square brackets] are T-SQL names | error | Spark, DuckDB | high | source |
| SYN-004 | @variables are T-SQL | error | Spark | high | source |
| SYN-005 | GO isn't SQL | error | Spark, DuckDB | high | source |
| SYN-006 | Backticks aren't T-SQL |
error | Warehouse, Endpoint, SQL database | high | source |
| SYN-007 | Not checked: couldn't read this statement | unverified | Spark, Warehouse, Endpoint, SQL database, DuckDB | medium | source |
| SYN-008 | "Double quotes" make a name, not text | warning | Warehouse, Endpoint, SQL database, DuckDB | medium | source |
| SYN-009 | construct is Spark SQL, not T-SQL | error | Warehouse, Endpoint, SQL database | high | source |
| SYN-010 | construct isn't in SQL database T-SQL | error | SQL database | medium | source |
| FN-001 | Not checked: function name | unverified | Spark, Warehouse, Endpoint, SQL database, DuckDB | low | source |
| FN-002 | ISNULL takes one argument in Spark SQL | error | Spark | high | source |
| FN-003 | name is a T-SQL function | error | Spark | high | source |
| FN-004 | name isn't a T-SQL function | error | Warehouse, Endpoint, SQL database | high | source |
| FN-005 | name is in preview | Warehouse: warning; Endpoint: warning | Warehouse, Endpoint | high | source |
| FN-006 | name isn't supported | error | Warehouse, Endpoint | high | source |
| TYP-001 | name can't be used in a Warehouse table | error | Warehouse | high | source |
| TYP-002 | The new table would get a name column | warning | Warehouse | medium | source |
| TYP-003 | name(n) keeps more than 6 digits of seconds | error | Warehouse | high | source |
| TYP-004 | uniqueidentifier is stored as binary | information | Warehouse | high | source |
| TYP-005 | name(max) holds at most 16 MB | information | Warehouse | high | source |
| DDL-001 | name aren't supported | error | Warehouse, Endpoint | high | source |
| DDL-002 | Computed columns aren't supported | error | Warehouse | high | source |
| DDL-003 | Unique indexes aren't supported | error | Warehouse, Endpoint | high | source |
| DDL-004 | name must be form | error | Warehouse | high | source |
| DDL-005 | ## global temp tables aren't supported | error | Warehouse, Endpoint | high | source |
| DDL-006 | #temp table without distribution | information | Warehouse | high | source |
| DDL-007 | name | Warehouse: error | Warehouse | high | source |
| DDL-008 | Name 'name' isn't allowed | error | Warehouse | high | source |
| DDL-009 | More than 1,024 columns | error | Warehouse | high | source |
| DDL-010 | Multi-column statistics aren't supported | error | Warehouse, Endpoint | high | source |
| DDL-011 | CREATE USER isn't supported | error | Warehouse, Endpoint | high | source |
| DDL-012 | Not checked: name | unverified | Warehouse | low | source |
| DDL-013 | External tables aren't supported | error | Warehouse, Endpoint | high | source |
| DDL-014 | Column name 'name' isn't allowed | error | SQL database | high | source |
| DDL-015 | Logins aren't supported | error | Warehouse, Endpoint, SQL database | high | source |
| EP-001 | The SQL analytics endpoint can't change tables | error | Endpoint | high | source |
| DB-001 | name isn't supported | error | SQL database | high | source |
| DML-001 | name isn't supported | error | Warehouse, Endpoint | high | source |
| DML-002 | Recursive CTE | Warehouse: error; Endpoint: error; Spark: unverified | Warehouse, Endpoint, Spark | high | source |
| DML-003 | Nested CTEs are in preview | warning | Warehouse, Endpoint | high | source |
| DML-004 | System and user tables in one query | error | Warehouse, Endpoint | high | source |
| DML-005 | Not checked: name | unverified | Warehouse, Endpoint | low | source |
| DML-006 | MERGE and write conflicts | information | Warehouse | high | source |
| DML-007 | Three-part name | Warehouse: information; Endpoint: information; SQL database: warning | Warehouse, Endpoint, SQL database | high | source |
| DML-008 | Four-part name | Warehouse: unverified; Endpoint: unverified; SQL database: error | Warehouse, Endpoint, SQL database | medium | source |
| TRX-001 | Isolation level can't be changed | warning | Warehouse, Endpoint | high | source |
| TRX-002 | name aren't supported | error | Warehouse, Endpoint | high | source |
| TRX-003 | Distributed transactions aren't supported | error | Warehouse, Endpoint, SQL database | high | source |
| TRX-004 | Snapshot isolation and conflicts | information | Warehouse | high | source |
| SEM-001 | = NULL is never true | warning | Spark, Warehouse, Endpoint, SQL database, DuckDB | high | source |
| SEM-002 | Text compares case-sensitively | information | Warehouse, Endpoint | high | source |
| SEM-003 | Whole-number division drops the fraction | warning | Warehouse, Endpoint, SQL database | high | source |
| SEM-004 | NOT IN with a subquery | information | Spark, Warehouse, Endpoint, SQL database, DuckDB | high | source |
| SEM-005 | The clock is UTC | information | Warehouse, Endpoint, SQL database | medium | source |
| SEM-006 | Collation name | warning | Warehouse | medium | source |
| DES-001 | DROP name deletes it | warning | Spark, Warehouse, Endpoint, SQL database, DuckDB | high | source |
| DES-002 | TRUNCATE deletes every row | warning | Spark, Warehouse, Endpoint, SQL database, DuckDB | high | source |
| DES-003 | name without WHERE changes every row | warning | Spark, Warehouse, Endpoint, SQL database, DuckDB | high | source |
| DES-004 | name replaces the table | warning | Spark, DuckDB | high | source |
| DES-005 | DROP COLUMN deletes the column's data | warning | Spark, Warehouse, Endpoint, SQL database, DuckDB | high | source |
| LOC-001 | Changes data in Fabric, not here | warning | Spark | high | source |
| LOC-002 | Regular expressions differ on this PC | warning | Spark | medium | source |
| LOC-003 | Date pattern is translated on this PC | warning | Spark | medium | source |
| LOC-004 | name gives a different value each run | information | Spark, DuckDB | high | source |
| LOC-005 | Decimal results can differ | information | Spark | medium | source |
| LOC-006 | name has no fixed order | warning | Spark | medium | source |
| LOC-007 | Each run starts fresh | information | Spark | high | source |
| LOC-008 | DuckDB SQL runs only on this PC | information | DuckDB | high | source |
| LOC-009 | name reads files on this PC | information | Spark, DuckDB | high | source |
How it's built and tested#
sidecar/fabric_desktop/sqlcompat/:profiles.pydescribes each engine (statement categories, unsupported types and their alternatives, identifiers, transactions, DDL and DML, semantic differences, confidence and sources);rules.pyholds the rules, each naming its engines, severity, confidence and source;analyzer.pysplits the SQL into statements (at;and T-SQL'sGO), reads each with sqlglot and the engine's tokenizer, applies the rules and builds the report. Rules work on tokens first, so they still find problems, at exact positions, in statements sqlglot can't read.- The engine methods are
sql_analyze,sql_compat_profilesandsql_compat_export. sidecar/tests/fixtures/sql_compat_v1.jsonlholds 192 cases: the SQL, the engine, the expected outcome, the exact set of rules expected and where the first finding is. 35 of them are false-positive guards, SQL that must not be flagged (Spark array indexes,ISNULL(a, b)in T-SQL,UPDATE ... SET x = NULL, keywords inside strings and comments, triggers in a SQL database).sidecar/tests/test_sql_compat.pyruns them.- Changing a rule means moving
RULE_VERSIONon, reviewing the fixtures and updating this page.
Need a hand?
Find a fix in troubleshooting, or share a reproducible issue with the community.
Get support ↗Improve this guide on GitHub ↗