Skip to content
Docs

SQL Dialects

BifrostQL abstracts database-specific SQL generation through the ISqlDialect interface. Each dialect handles identifier quoting, pagination syntax, type mapping, and upsert strategies for its target database.

DatabasePackageProvider keyStatus
SQL ServerBifrostQL.SqlServersqlserverProduction
PostgreSQLBifrostQL.NgsqlpostgresProduction
MySQLBifrostQL.MySqlmysqlProduction
SQLiteBifrostQL.SqlitesqliteExperimental

Set the provider in configuration:

{
"BifrostQL": {
"Provider": "postgres"
}
}
DatabaseStyleExample
SQL ServerBrackets[orders].[orderId]
PostgreSQLDouble quotes"orders"."orderId"
MySQLBackticks`orders`.`orderId`
SQLiteDouble quotes"orders"."orderId"
DatabaseSyntax
SQL ServerOFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY
PostgreSQLLIMIT @limit OFFSET @offset
MySQLLIMIT @limit OFFSET @offset
SQLiteLIMIT @limit OFFSET @offset

SQL Server requires an ORDER BY clause for OFFSET/FETCH pagination. BifrostQL adds a default order by primary key when no sort is specified.

DatabaseImplementation
SQL ServerMERGE ... WHEN MATCHED THEN UPDATE WHEN NOT MATCHED THEN INSERT
PostgreSQLINSERT ... ON CONFLICT (pk) DO UPDATE SET ...
MySQLINSERT ... ON DUPLICATE KEY UPDATE ...
SQLiteINSERT OR REPLACE INTO ...

SQL Server:

  • money, smallmoney map to Decimal
  • uniqueidentifier maps to String
  • nvarchar, nchar, ntext map to String

PostgreSQL:

  • serial, bigserial are treated as auto-increment
  • uuid maps to String
  • jsonb, json map to String
  • text[], integer[] map to [String], [Int]

MySQL:

  • tinyint(1) maps to Boolean (MySqlConnector returns bool for this type)
  • enum columns map to String
  • json maps to String
  • Column names are case-insensitive

SQLite:

  • Type affinity rules apply: INTEGER, REAL, TEXT, BLOB
  • No native BOOLEAN — uses INTEGER with 0/1
  • No native DATETIME — stored as text in ISO 8601 format

Add the dialect package alongside the core server package:

Terminal window
# SQL Server
dotnet add package BifrostQL.SqlServer
# PostgreSQL
dotnet add package BifrostQL.Ngsql
# MySQL
dotnet add package BifrostQL.MySql
# SQLite
dotnet add package BifrostQL.Sqlite

The dialect is selected at startup based on the Provider configuration value. Each dialect registers its own type mapper and SQL generator with the BifrostQL pipeline.

Implement the ISqlDialect interface to add support for a new database. The dialect must provide:

  • Identifier quoting
  • Parameter placeholder style
  • Pagination SQL generation
  • Upsert SQL generation
  • Type mapper (SQL types to GraphQL types)
  • Schema reader (database metadata to DbModel)

Register the dialect in your service configuration before calling AddBifrostQL.