Apache.Calcite.Data 1.0.1

dotnet add package Apache.Calcite.Data --version 1.0.1
                    
NuGet\Install-Package Apache.Calcite.Data -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Apache.Calcite.Data" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Apache.Calcite.Data" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Apache.Calcite.Data" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Apache.Calcite.Data --version 1.0.1
                    
#r "nuget: Apache.Calcite.Data, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Apache.Calcite.Data@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Apache.Calcite.Data&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Apache.Calcite.Data&version=1.0.1
                    
Install as a Cake Tool

Apache.Calcite.Data

NuGet

Apache.Calcite.Data is a native, in-process ADO.NET provider for Apache Calcite — the SQL parser, optimizer, and execution framework that powers many leading database and data-virtualization products.

The Calcite engine runs directly inside your .NET process via IKVM. There is no JDBC driver, no Avatica server, and no separate process. SQL flows from your DbConnection straight into Calcite's planner.

Why use this?

  • Standard ADO.NET — works with any code that understands DbConnection / DbCommand / DbDataReader, including Dapper, EF Core conventions, and generic data-access layers.
  • Federated queries — join CSV files, in-memory collections, REST adapters, JDBC databases, and custom Calcite schemas in a single SQL statement.
  • Rich SQL — standards-conformant SQL with window functions, lateral joins, MATCH_RECOGNIZE, and much more.
  • Code-driven schemas — register .NET objects as Calcite schemas, tables, and user-defined functions at runtime via the SchemaPlus API; no JSON model required.
  • No external dependencies — everything runs in-process; no server to provision or maintain.

Supported platforms

Targets .NET 8 and is verified on .NET 8 and .NET 10.

Install

dotnet add package Apache.Calcite.Data

Quick start — inline JSON model

The quickest way to connect is with an inline Calcite model that wires up one or more adapters:

using Apache.Calcite.Data;

const string model = """
{
  "version": "1.0",
  "defaultSchema": "SALES",
  "schemas": [
    {
      "name": "SALES",
      "type": "custom",
      "factory": "org.apache.calcite.adapter.csv.CsvSchemaFactory",
      "operand": { "directory": "sales" }
    }
  ]
}
""";

await using var conn = new CalciteConnection($"Model=inline:{model}");
await conn.OpenAsync();

await using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT \"NAME\", \"DEPTNO\" FROM \"EMPS\" WHERE \"DEPTNO\" = 10";

await using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
    Console.WriteLine($"{reader.GetString(0)}\t{reader.GetInt32(1)}");

Quick start — model file

Point Model at a JSON file on disk:

await using var conn = new CalciteConnection("Model=path/to/model.json;Schema=SALES");
await conn.OpenAsync();

Parameterized queries

Calcite uses positional ? placeholders (ODBC-style). Parameters are matched to placeholders by the order they are added to Parameters; the ParameterName is informational only.

await using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT \"NAME\" FROM \"EMPS\" WHERE \"DEPTNO\" = ? AND \"SALARY\" > ?";
cmd.Parameters.Add(new CalciteParameter("deptno", 10));
cmd.Parameters.Add(new CalciteParameter("salary", 50_000m));

await using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
    Console.WriteLine(reader.GetString(0));

Code-driven schemas

Register .NET objects as Calcite schemas directly — no JSON model required:

using org.apache.calcite.schema;

await using var conn = new CalciteConnection();
await conn.OpenAsync();

SchemaPlus root = conn.RootSchema;
root.add("MEM", new MyCustomSchema());   // any org.apache.calcite.schema.Schema implementation

await using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM \"MEM\".\"USERS\" ORDER BY \"ID\"";
await using var reader = await cmd.ExecuteReaderAsync();

Connection lifecycle

CalciteConnection is designed to be long-lived, mirroring the behaviour of Calcite's own JDBC driver. Opening a connection initialises the in-process Calcite engine, parses and validates the model, and builds the schema — work that is relatively expensive and intended to be amortised over many queries. Keep one connection (or one CalciteDataSource) open for the lifetime of a logical data source rather than opening and closing connections per query.

Thread safety:

  • The ADO.NET layer (CalciteConnection, CalciteCommand, CalciteDataReader, etc.) is thread-safe: multiple threads may share a single connection and issue concurrent commands against it.
  • The Calcite engine layer (schemas, the planner, RootSchema, etc.) is thread-safe for concurrent reads and queries. Mutating the schema (e.g. calling RootSchema.add(...)) while queries are in-flight is Calcite's concern, not this provider's; refer to the Apache Calcite documentation for its concurrency guarantees.

Using DbDataSource (.NET 7+)

CalciteDataSource implements the modern DbDataSource pattern for dependency-injection and pooled-connection scenarios:

using Apache.Calcite.Data;

// Create once and share across the application (e.g. register as a singleton in DI).
await using var dataSource = new CalciteDataSource("Model=path/to/model.json");

await using var conn = await dataSource.OpenConnectionAsync();
await using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT COUNT(*) FROM \"ORDERS\"";
var count = await cmd.ExecuteScalarAsync();
Console.WriteLine($"Order count: {count}");

Using DbProviderFactory

using System.Data.Common;
using Apache.Calcite.Data;

// Register once at startup.
DbProviderFactories.RegisterFactory("Apache.Calcite.Data", CalciteProviderFactory.Instance);

// Resolve anywhere.
var factory = DbProviderFactories.GetFactory("Apache.Calcite.Data");
await using var conn = factory.CreateConnection()!;
conn.ConnectionString = "Model=path/to/model.json";
await conn.OpenAsync();

Connection string reference

All keys are exposed as typed properties on CalciteConnectionStringBuilder. Unknown keys are preserved and forwarded to the engine.

Key Type Description
Model string Path/URI to a Calcite model JSON file, or inline:<json> for an embedded model.
Schema string Default schema name when identifiers are unqualified.
CaseSensitive bool Whether identifier lookup is case-sensitive (default: true).
Conformance string SQL conformance level: DEFAULT, STRICT_2003, PRAGMATIC_2003, etc.
Lex string Lexical policy: ORACLE (default), MYSQL, MYSQL_ANSI, SQL_SERVER, JAVA, BIG_QUERY.
Quoting string Quote style: DOUBLE_QUOTE, BACK_TICK, BACK_TICK_BACKSLASH, BRACKET.
QuotedCasing string How quoted identifiers are stored: UNCHANGED, TO_UPPER, TO_LOWER.
UnquotedCasing string How unquoted identifiers are stored: UNCHANGED, TO_UPPER, TO_LOWER.
Fun string Extra function libraries: standard (default), oracle, spatial, or comma-separated combinations.
TimeZone string Session time zone, e.g. UTC or gmt-3. Defaults to the JVM time zone.
Conformance string SQL conformance level.
DefaultNullCollation string How NULLs sort when NULLS FIRST/NULLS LAST is not specified. Default: HIGH (Oracle behaviour).
ForceDecorrelate bool Whether the planner aggressively de-correlates subqueries (default: true).
MaterializationsEnabled bool Whether the planner may use materializations (default: false).
TypeCoercion bool Whether implicit type coercion is applied during validation (default: true).
parserFactory string Custom SQL parser factory class, e.g. org.apache.calcite.sql.parser.ddl.SqlDdlParserImpl#FACTORY.

Identifier casing

Calcite's default lexer (Lex=ORACLE) follows standard SQL rules:

Identifier kind Normalized to Compared
Unquoted (emps) Upper case (EMPS) Case-sensitive
Quoted ("Emps") Unchanged (Emps) Case-sensitive

Most built-in adapters (CSV, JDBC against H2/HSQLDB/Oracle) expose names in upper case, so unquoted identifiers work naturally with them.

If your schema uses mixed- or lower-case names, quote them:

cmd.CommandText = """SELECT "Name", "DeptNo" FROM "Emps" WHERE "DeptNo" = 10""";

Or switch to a case-insensitive lexer:

// Lex=MYSQL_ANSI: unquoted identifiers are left unchanged, matching is case-insensitive.
await using var conn = new CalciteConnection("Model=inline:{...};Lex=MYSQL_ANSI");

Accessing the Calcite engine directly

CalciteConnection exposes Calcite-native objects as typed .NET properties for advanced scenarios:

Property Java type Purpose
RootSchema org.apache.calcite.schema.SchemaPlus Add/remove schemas and tables at runtime.
TypeFactory org.apache.calcite.adapter.java.JavaTypeFactory Construct Calcite RelDataType instances.
Config org.apache.calcite.config.CalciteConnectionConfig Inspect resolved connection configuration.

These properties are only valid while the connection is open.

Package Purpose
Apache.Calcite.Adapter.AdoNet Expose any ADO.NET data source as a federated Calcite schema with query pushdown.
Apache.Calcite.Extensions .NET helper types for working with Calcite connection properties and IKVM interop.

Further reading

License

Apache License 2.0.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 39 5/26/2026
1.0.0 37 5/26/2026