Query Language Alternative
データ分析において欠かせない存在であるSQLは、非常に柔軟な表現力を持ち、50年以上にわたり使われ続けています。Qualtは、刻々と変化するデータと現代のチーム開発に対応するため、SQLを言語レベルで再設計します。
クエリを使い捨てにせず、蓄積するチームの財産に
静的解析を備えたモジュールシステムにより、巨大なクエリを再利用可能なパーツへ分割できます。変更の影響を把握しながら、プロジェクトを継続的に発展させられます。
-- モジュールを定義
MODULE ranged_orders(
start_date TIMESTAMP DEFAULT "2026-01-01"
) =>
SELECT
order_id,
num_of_item
FROM thelook_ecommerce.orders
WHERE shipped_at > start_date;
-- モジュール呼び出し
SELECT avg(num_of_item) AS avg_num_of_item
FROM ranged_orders()
クエリそのものがドキュメントとなり、設計意図を伝達
SQLだけでは表現できないメタ情報や注釈を、クエリに直接書き込めます。書き込んだ情報は統合管理され、他の開発者やツールからすばやくアクセスすることが可能です。
-- マテリアライズ方法の指定
@materialize(materialize_type="table")
select
-- 連番の注文ID
order_id @unique @reference(target=order_items.id),
sum(product_retail_price) as total_retail_price,
sum(cost) as total_cost,
FROM inventory_items AS ii
LEFT JOIN order_items AS oi ON ii.id = oi.inventory_item_id
GROUP BY order_id
クエリ開発に必要な情報を統合した開発環境
プロジェクト全体の既存クエリやテーブル情報など、実装に必要な情報をエディタに統合。クエリを記述しながら、コンテキストを失うことなく開発を進められます。

SQLをアップデートする
使い慣れたSQLの感覚を維持しつつ、その柔軟性を損なうことなく、より明快で一貫性のある構文へ再設計しました。
-- FROMから書き始められるSELECT文
QUERY FROM thelook_ecommerce.orders
WHERE shipped_at
BETWEEN "2026-01-01" AND "2026-02-28"
GROUP BY order_id
SELECT
order_id,
-- パラメータ構文のシンプル化
-- 2nd parameter true => ignore nulls
first_value(num_of_items, true)
Qualt をクエリ言語・環境として価値あるものにするため、以下の方針に従って開発を進めています。
ソースコードやデータの解析処理の高速な応答を追求します。なによりもまずクエリを書く環境として快適なものであることを目指します。開発の継続によって変化していくボトルネックに粘り強く向き合います。
データベースのデータ・メタデータに関する機能を明確にスコープに入れます。ユーザーがデータベースとクエリを行き来する手間を減らし、クエリ記述とデータ探索の距離を縮めます。
複数のデータベースに対応するとともに、対応データベースが増えても現実的なコストで開発が継続できるように言語仕様を定めます。Write Once, Run Any Databaseにするのではなく、型名や関数はなるべくバックエンドデータベースのものをそのまま使用し、複雑な方言は構文解析をパスして直接記述できるようにします。
クエリを分析した結果得られる情報は機械で処理できる形式でも出力できるようにします。外部ツールとの連携だけではなく、LLMから利用されることを考慮してCLIを実装します。
チーム開発のためのSQLへ
生成AIがデータ分析業務を変革する中、SQLはエンジニア、ビジネスユーザー、AIを結ぶ共通言語としての役割を担います。
本プロジェクトは、SQLそのものをアップデートし、現代に適したプロダクションレベルの言語へと進化させます。
Qualtは今後、一部のオープンソース化やCodatumへの組み込みを予定しています。
現在開発中のため、SQLを使う上での課題や、欲しい機能についてぜひご意見をお聞かせください😉
株式会社CODATUMは、SQLを軸とした製品開発を通じて、チームによるデータ活用を実現していきます。
Qualtは、コンパイラを含むコマンドラインツールとLSP Server / Clientで構成されています。

ソースコードを静的に解析することで、クエリを実行せずに各モジュールの定義や状態を把握します。
コーディング中は構文が不完全になることがありますが、QualtはLSP対応を前提に、トークン欠けに強い文法定義を採用。トークン欠損は意味解析フェーズでエラーとして検出し、構文解析失敗時も前回成功時の解析結果とコード変更履歴から適切な言語サポートを提供します。

意味解析では、スコープに従った識別子の実体確定と型エラーチェックを実施。さらに、データベース・テーブルのスキーマや統計情報を活用し、ユーザー定義の制約チェックや言語サポートを実現します。
意味解析によって生成されるセマンティック情報は以下の3つで構成されます。
データベース状態は刻々と変化するため、コード変更とは独立したサイクルでデータベース情報を更新する設計となっています。
コードに変更がある場合、セマンティック情報は各モジュール(exsqlファイル)ごとに保持され、モジュール間の依存関係グラフから変更があったモジュールとその依存モジュールのみを再計算の対象とします。これにより、大規模プロジェクトでも高速な型チェックと言語サポートを実現します。
SELECT order_id, num_of_item FROM ranged_orders()上記クエリのASTノードに対して、以下のようなセマンティック情報が付与されます。
| ASTノード | ノード種別 | データ型 | 参照先・解決方法 |
|---|---|---|---|
| SELECT order_id, num_of_item FROM ranged_orders() | SELECT文 | TABLE(order_id INT64, num_of_item INT64) | - |
| └ order_id | フィールド参照 | INT64 | ranged_ordersの変数テーブルから解決 |
| └ num_of_item | フィールド参照 | INT64 | ranged_ordersの変数テーブルから解決 |
| └ FROM ranged_orders() | FROM句 | TABLE(order_id INT64, num_of_item INT64) | - |
| └ ranged_orders() | モジュール呼び出し | TABLE(order_id INT64, num_of_item INT64) | module:ranged_orders |
| └ ranged_orders | モジュール参照 | MODULE | 定義済みモジュール |
| └ () | パラメータリスト | - | デフォルトパラメータで実行 |